2011-12-13 13 views
5

Jak ocenia się następujące wyrażenie?Autoboxing w Javie

klasa

Student:

public class Student 
{ 
    private Integer id; 
    // few fields here 

    public Integer getId() 
    { 
     return id; 
    } 

    public void setId(Integer id) 
    { 
     this.id=id; 
    } 

    //setters and getters 
} 

I w jakiś sposób:

{ 
    int studentId; 

    // few lines here 

    if(studentId==student.getId()) // **1. what about auto-unboxing here? Would it compare correctly? I am not sure.** 
    { 
     //some operation here 
    } 
} 
+2

Nie używaj klas opakowania, chyba że koniecznie musisz. – mre

+0

Tak. to, co zrobiłeś, mogłoby działać. Nie jestem pewien, czy spytałeś o cokolwiek innego? – Guillaume

+0

+1 za niewykorzystanie klas opakowania: zły potencjalny efekt uboczny zawiera niechciany (i ukryty) wyjątek NullPointerException wygenerowany przez twój kod – Guillaume

Odpowiedz

4

Tak, to będzie pracować jest równoważna

studentId==student.getId().intValue() 

tak długo student.id nie null .

+4

Po prostu z ciekawości, jakie są zasady boksowania i rozpakowywania? Chodzi mi o to, dlaczego Java decyduje się na ** unbox ** 'Integer' zamiast ** box **' int'? – bezmax

+1

to odpowiednik czy student.id ma wartość null czy nie –

+0

Może być, ponieważ 'int' po lewej stronie? – red1ynx

1

Tak, będzie dobrze. Ale zwykle nie zaleca się używania klasy opakowania, dopóki nie ma innej możliwości.

3

Tak, to zadziała, ale zauważ!

Jeżeli wartość id Integer w Student jest null, trzeba będzie NullPointerException podczas oceny

studentId == student.getId(); 

Należy również zauważyć, że autoboxing będzie mieć pewne koszty wykonania, dlatego należy używać go tylko wtedy, gdy trzeba.

Czytaj więcej tutaj: http://docs.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html

1

Porównanie

studentId==student.getId() 

będzie działać, ale będzie rzucać NullPointerException jeśli student jest null.

Zasadniczo autoboxing preferuje prymitywy, to znaczy konwertuje Integer na int, gdzie to możliwe, a nie na odwrót. Twój przykład pokazuje jeden dobry powód tego, ponieważ równość dla obiektów referencyjnych jest trudna. Więc to jest możliwe:

studentId==student.getId().intValue() 

aby mogło być prawdziwe, ale

new Integer(studentId)==student.getId() 

się fałszywe, ponieważ podczas gdy oni mają taką samą wartość, że nie jesteś sam obiekt.

1

Tak to będzie działać, jak to będzie konwertować prawy operand do odpowiednich typ liczbowy, zgodnie z java specyfikacji języka:

Jeśli argumenty z operatorem równości są zarówno typu numerycznego, albo jeden jest numeryczna typ i drugi jest zamienny (§5.1.8) na typ numeryczny, binarna promocja numeryczna jest wykonywana na operandach (§5.6.2).

corresponding paragraph in jls

Więc rzeczywiście którykolwiek z argumentów może być typu liczbowego dla Java autounbox drugiego.

A następnie §5.1.8 mówi, że konwersje obejmują rozpakowywanie.corresponing paragraph in jls

1

Według specyfikacji http://docs.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html

Więc kiedy należy użyć autoboxing i unboxing? Używaj ich tylko wtedy, gdy występuje "niedopasowanie impedancji" pomiędzy typami odniesienia i prymitywami, na przykład, gdy musisz umieścić wartości liczbowe w kolekcji. Nie jest właściwe stosowanie autoboxingu i rozpakowywania w przypadku obliczeń naukowych lub innych kodów numerycznych wrażliwych na wydajność. Liczba całkowita nie jest substytutem int; autoboxing i unboxing zamazują rozróżnienie między typami pierwotnymi i referencyjnymi, ale nie eliminują go.

Na wskazany tylko przypadki korzystania z klasy otoki (Integer, itd.) Są, jeśli chcesz trzymać wartości numerycznych w kolekcji, lub null jest dopuszczalną wartość dla przypadków użycia. to jest to!

Efekt uboczny to niepożądany potencjał NullPointerException i spadek wydajności.