Автобокс в 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).

соответствующий абзац в jls

Так что на самом деле любой из операндов может иметь числовой тип, чтобы java мог автоматически установить другой.

А затем §5.1.8 говорит, что преобразования включают преобразование без коробки. соответствующий абзац в JLS

Другие вопросы по тегам