ciekawostka

0

ostatnio na rozmowie kwalifikacyjnej dostałem bardzo ciekawy kod. Zawsze byłem przekonany, że kompilator javy nie pozwoli wykonać przypisania w ifie np if( zmienna = inna zmienna). I dostałem następujący kod:

		boolean b = false;
		boolean b2 = true;
		if(b = (b = b2)){
			System.out.println("TRUE");
		}else{
			System.out.println("FALSE");
		}

I drugi ciekawy fragment:

		boolean b = false;
		if(b == (b = true)){
			System.out.println("TRUE");
		}else{
			System.out.println("FALSE");
		}

wynik:
1 - true
2 - false (z czego można odnieść wrażenie że b jest różne od b)

0

że kompilator javy nie pozwoli wykonać przypisania w ifie

niby dlaczego?

kod imho wcale taki zagadkowy nie jest ;]

0
  1. zawsze będzie true, bo masz przypisania do true.
  2. false == true, ale tylko na poziomie lokalnym
0

Można sobie włączyć warningi przy kompilacji wykrywające przypisania booleanów w ifach.
IMHO głupie pytanie na rozmowe kwalfikacyjną. Po co z takich pierdółek pytać?

0

Ale to przecież stuprocentowo poprawny kod, nie wiem czemu się dziwisz - operator przypisania zwraca w Javie obiekt będący z lewej strony, a jako warunek trzeba użyć typu boolean - b i b2 są, wynik przypisania w takim razie też, porównanie zawsze daje w wyniku boolean... Wszystko w zgodzie z językiem.

0

@rnd, bo pytający też z takich dupereli był pytany. pamiętam jak kiedyś pytali mnie o gwiazdki w EQLu. Kretynizm, ale pytają.

0

Właśnie takie testy na "znajomość języka" doprowadzają często do tego, że na rekrutacji odwala się dobrych programistów z doświadczeniem, a prześlizgują się tacy, co wcześniej zrobili pięćdzięsiąt takich testów. Podobnie z wszelkimi zagadkami "na inteligencję".

A z Javy widziałem jeszcze coś takiego:

Integer a = 12;
Integer b = 12;
System.out.println(a.equals(b));
System.out.println(a == b);

Integer c = 2048;
Integer d = 2048;
System.out.println(c.equals(d));
System.out.println(c == d);

Nie będę podpowiadał, każdy może sobie sprawdzić sam. W każdym razie wynik nie jest zgodny z intuicją - jak ktoś nie czytał dokładnie dokumentacji, to może nie rozwiązać. ;)

0

@Krolik, nie mam nastroju na dokładne czytanie dokumentacji (za gorąco). Dlaczego

Integer a = 12;
Integer b = 12;
System.out.println(a == b); //true

Integer c = 2048;
Integer d = 2048;
System.out.println(c == d); //false

???

0
Krolik napisał(a)

Właśnie takie testy na "znajomość języka" doprowadzają często do tego, że na rekrutacji odwala się dobrych programistów z doświadczeniem, a prześlizgują się tacy, co wcześniej zrobili pięćdzięsiąt takich testów. Podobnie z wszelkimi zagadkami "na inteligencję".

A z Javy widziałem jeszcze coś takiego:

Integer a = 12;
Integer b = 12;
System.out.println(a.equals(b));
System.out.println(a == b);

Integer c = 2048;
Integer d = 2048;
System.out.println(c.equals(d));
System.out.println(c == d);

> 
> Nie będę podpowiadał, każdy może sobie sprawdzić sam. W każdym razie wynik nie jest zgodny z intuicją - jak ktoś nie czytał dokładnie dokumentacji, to może nie rozwiązać.  ;)


Nie mam zielonego pojęcia dlaczego tak się dzieje. a==b zwraca true gdy liczby sa ponizej 128 tak więc to coś ma wspólnego z przypisywaniem byte. Mógłby ktoś wyjaśnić dlaczego tak sie dzieje?
0

W przypadku boxingu zmiennych typu boolean, byte, short -128-127, int -128-127 i char \u0000-\u007F są wykorzystane obiekty typu immutable.
http://today.java.net/pub/a/today/2005/03/24/autoboxing.html#immutable_objects

0

Ale masakre macie w tej Javie z tym c == d jesli faktycznie zwraca to false.

Co do pierwszego posta to drugi przypadek mnie na pierwszy rzut oka zaskoczyl... bo i owszem teoretycznie to jest poprawnie ale jak taka teoria ma sie do praktyki? Dopiero jak sie chwilke nad tym zastanowisz to dojdziesz do poprawnej odpowiedzi, no tylko, po co utrudniac sobie zycie?... jakby jakis programista z mojego zespolu takie cos w kodzie uzyl to by dostal ostry opieprz.

No ale fakt, to rozmowa kwalifikacyjna, gdzie musza pokazac Ci, ze jednak jestes ten glupi i Twoje wymagania co do stawki sa przesadzone.

0

Programista Javy wie, że operator == porównuje referencje obiektów (a nie ich zawartość). Zatem zaskoczeniem będzie, że porównanie a==b zwraca true, to że c==d zwraca false jest natomiast "oczywiste". Co więcej programista Javy nie użyje operatora == do porównania zawartości obiektów.

0

I dlatego ten kod podałem jako przykład bezsensownego testu na umiejętność programowania.

A co do zachowania Javy, wbrew pozorom, nie jest to wcale takie porąbane - programiści Suna doszli do wniosku, że małe liczby (-128 - 127) są w programach dużo częściej używane niż duże liczby. Ponieważ jest ich tylko 256, to można zrobić cache obiektów typu Integer - dzięki temu boxing małych liczb działa dużo szybciej i nie wymaga alokacji obiektów na stercie.

Co do immutable, to każdy Integer jest immutable, nie tylko mały. Więc teoretycznie taki cache mogliby zbudować dla całego zakresu, ale tylko teoretycznie, bo potrzeba by na niego... 64GB.

0

Ale w sumie da się wymyślić kod, w którym ta właściwość spowodowała by bug. Chociażby kontener, który przechowuje unikalne referencje do obiektów (wartość samego obiektu w kontenerze nie musiała by być unikalna). W takim kontenerze obiekty autoboxowane z byte nie powtarzały by się.

0

Dla każdej właściwości języka da się skonstruować taki kod, że ta właściwość spowoduje bug.
Np. dla pętli while można napisać:

while(true);

Co odróżnia jednak tutaj Javę od C i C++, to jest to, że standard dokładnie określa jakie powinno być zachowanie. Nie ma "undefined behaviour". No i też trzeba nieźle się postarać, żeby to sprawiło kiedyś problem. Programuję już dośc długo i nigdy ta własność języka nie spowodowała mi buga.

0

Wiem, że taki spowodować błąd tą własnością języka bardzo trudno :)

jeśli nawet ktoś chciałby na polegać na równości, bądź nierówności referencji, to sobie zawsze nowe Integery przez new może tworzyć i problemu nie ma

Ale najpierw trzeba wiedzieć o tej własności, żeby zdecydować się na przydzielanie przez new. Chodziło mi raczej, że te pytanie na rozmowe nie jest takie bezsensu jak pierwsze.

0

Uwazam jednak, ze jest, gdyz 99% ludzi i tak nigdy czegos takiego nie uzyje i nigdy nawet na oczy nie zobaczy. Tak wiec, po co sprawdzac cos co w praktyce nie wystepuje, jak nie po to by wytknac komus niewiedze? A to juz trick psychologiczny przed rozmowa o stawce. (nie mowie o c == d w javie, skoro dla tych programistow to oczywiste, lecz o przykladzie z 1 posta).

0

@Krolik, zepsuć można za pomocą tego mechanizmu wiele rzeczy np:


private final Integer LOCK_AND_COUT = 1000;

void m(){
  synchronized(LOCK_AND_COUT){
     for(int i = 0; i< LOCK_AND_COUT; i++)
       //operacja do synchronizacji.
  }
}

I już nie ma synchronizacji.

@wasiu, byś się zdziwił, bo wiele osób wykorzystuje nieświadomie autoboxing i popełnia błędy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1