Автобокс в Java
Как оценивается следующее выражение?
Студенческий класс:
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
}
И в некотором методе:
{
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
}
}
6 ответов
Да, это будет работать, это эквивалентно
studentId==student.getId().intValue()
как долго студент.ид не null
,
Да, это будет работать, но обратите внимание!
Если идентификатор целочисленного значения в Student равен null, у вас будет NullPointerException при оценке
studentId == student.getId();
Также обратите внимание, что автобокс будет иметь некоторые затраты производительности, поэтому вы должны использовать его только в случае необходимости.
Подробнее читайте здесь: http://docs.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html
Да, это будет работать нормально. Но обычно не рекомендуется использовать класс-оболочку, пока не будет другого пути.
Сравнение
studentId==student.getId()
будет работать, но бросит NullPointerException
если student
является null
,
Как правило, автобокс предпочитает примитивы, т.е. Integer
в int
где это возможно, а не наоборот. Ваш пример показывает одну хорошую причину этого, так как равенство для ссылочных объектов сложно. Так что это возможно для:
studentId==student.getId().intValue()
чтобы быть правдой, но
new Integer(studentId)==student.getId()
быть ложным, поскольку, хотя они имеют одинаковое значение, они не являются одним и тем же объектом.
Согласно спецификациям, http://docs.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html
Итак, когда вы должны использовать автобокс и распаковку? Используйте их только тогда, когда существует "несоответствие импеданса" между ссылочными типами и примитивами, например, когда вам нужно поместить числовые значения в коллекцию. Не рекомендуется использовать автобокс и распаковку для научных вычислений или другого числового кода, чувствительного к производительности. Integer не является заменой для int; Автобокс и распаковка стирают различие между примитивными типами и ссылочными типами, но они не устраняют это.
Единственные рекомендуемые случаи использования классов-обёрток (Integer
и т. д.), когда вы хотите вставить числовые значения в коллекцию, или null
является приемлемым значением для ваших сценариев использования. Вот и все.
Побочный эффект включает нежелательный потенциал NullPointerException
и снижение производительности.
Да, это будет работать, так как он преобразует правый операнд в соответствующий числовой тип в соответствии со спецификацией языка Java:
Если оба операнда оператора равенства имеют числовой тип или один имеет числовой тип, а другой преобразуется (§5.1.8) в числовой тип, двоичные числовые преобразования выполняются над операндами (§5.6.2).
Так что на самом деле любой из операндов может иметь числовой тип, чтобы java мог автоматически установить другой.
А затем §5.1.8 говорит, что преобразования включают преобразование без коробки. соответствующий абзац в JLS