Автобокс в Java - PullRequest
       16

Автобокс в Java

5 голосов
/ 13 декабря 2011

Как оценивается следующее выражение?

Студенческий класс:

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 ]

4 голосов
/ 13 декабря 2011

Да, это будет работать, это эквивалентно

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

, пока long.id не равен null.

3 голосов
/ 13 декабря 2011

Да, это будет работать, но обратите внимание!

Если идентификатор целочисленного значения в Student равен null, при оценке

у вас будет исключение NullPointerException
studentId == student.getId();

Обратите внимание также, что автобокс будет иметь некоторые затраты производительности, поэтому вы должны использовать его только в случае необходимости.

Подробнее здесь: http://docs.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html

1 голос
/ 13 декабря 2011

В соответствии со спецификациями, http://docs.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html

Так когда следует использовать автобокс и распаковку?Используйте их только тогда, когда существует «несоответствие импеданса» между ссылочными типами и примитивами, например, когда вам нужно поместить числовые значения в коллекцию.Не рекомендуется использовать автобокс и распаковку для научных вычислений или другой чувствительный к производительности числовой код.Integer не является заменой для int;Автобокс и распаковка стирают различие между примитивными типами и ссылочными типами, но они не устраняют это.вставлять числовые значения в коллекцию, или null является приемлемым значением для ваших сценариев использования.Вот и все.

Побочный эффект включает нежелательный потенциал NullPointerException и снижение производительности.

1 голос
/ 13 декабря 2011

Да, это будет работать, так как преобразует правый операнд в соответствующий числовой тип в соответствии со спецификацией языка Java:

Если оба операнда оператора равенства имеют числовой тип, или один имеет числовой тип, а другой может быть преобразован (§5.1.8) в числовой тип, двоичные числовые преобразования выполняются над операндами (§5.6.2 ).

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

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

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

1 голос
/ 13 декабря 2011

Сравнение

studentId==student.getId()

будет работать, но выкинет NullPointerException, если student равно null.

Как правило, автобокс предпочитает примитивы, т.е. он будет конвертироватьот Integer до int, где это возможно, а не наоборот.Ваш пример показывает одну хорошую причину для этого, так как равенство для ссылочных объектов сложно.Таким образом, возможно:

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

быть истинным, а

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

- ложным, поскольку, хотя они имеют одинаковое значение, они не являются одним и тем же объектом.

1 голос
/ 13 декабря 2011

Да, он будет работать нормально.Но, как правило, не рекомендуется использовать класс-оболочку, пока не будет другого пути.

...