В чем разница между (Integer) y и новым целым (y) в java?

В чем разница между следующим:

Integer in = (Integer)y;

и

Integer in = new Integer(y);

Я хочу преобразовать тип int в тип Integer и наоборот. Вот мой код для этого:

public class CompareToDemo {

  public static void main(String[] args) {
    // Integer x=5;
    int y=25;

    System.out.println(y+" this is  int variable");

    Integer in = (Integer)y;

    //Integer in = new Integer(y);

    if(in instanceof Integer){
      System.out.println(in +" this is Integer variable");
    }
  }
}

Ответы

Ответ 1

Если все, что вы хотите сделать, это преобразовать примитив int в объект Integer у вас есть четыре варианта

   Integer in = (Integer)y;         // 1 explicit cast
   Integer in = y;                  // 2 implicit cast (autoboxing)
   Integer in = new Integer(y);     // 3 explicit constructor
   Integer in = Integer.valueOf(y); // 4 static factory method

Наиболее предпочтительным способом является 2 (автобоксинг). Явный конструктор (3) является менее предпочтительным, так как он может иметь небольшой успех.

Кроме того, они не являются строго эквивалентными. Рассмотрим:

public static void main(String[] args) {
    int x = 25;
    Integer a = new Integer(x);
    Integer b = new Integer(x);
    System.out.println(a == b);     // false
    Integer c = Integer.valueOf(x);
    Integer d = Integer.valueOf(x);
    System.out.println(c == d);     // true
    Integer e = (Integer)x;
    Integer f = (Integer)x;
    System.out.println(e == f);     // true
}

Это потому, что маленькие целые кешируются (подробности здесь).

Ответ 2

Коротко говоря,

  • Строка Integer in = (Integer)y; использует ненужный приведение.
  • Строка Integer in = new Integer(y); создает экземпляр Integer.

В каждом случае подробно

Сначала рассмотрим случай с явным литьем.

Integer i = (Integer)10;

Компилятор понимает, что 10 является примитивным типом int и тем фактом, что он должен быть обернут его Integer, чтобы скомпилировать его. Кажется, javac сделает следующее:

Integer i = (Integer)Integer.valueOf(10);

Но компилятор достаточно умен, чтобы делать ненужное кастинг, (Integer) просто будет опущен:

Integer i = Integer.valueOf(10);

Далее, есть случай с созданием экземпляра.

Integer i = new Integer(10);

Здесь все просто. В любом случае будет создан новый экземпляр класса Integer. Но, как говорится в документации, обычно это не подходит:

Редко использовать эти конструкторы. Статические фабрики valueOf(), как правило, являются лучшим выбором, так как это, вероятно, даст значительно лучшую производительность пространства и времени.

Заключение

В повседневной записи кода мы обычно используем autoboxing and unboxing. Они представляют собой автоматические преобразования между примитивными типами и соответствующими классами оболочек объектов (введены в Java 5). Поэтому вам не нужно много думать о методах Xxx.valueOf(xxx) и .xxxValue(). Это так удобно, не так ли?

Integer i = 10; // autoboxing
int j = i; // unboxing

Ответ 3

Для каждого примитивного типа в java существует соответствующий класс-оболочка. Вы можете конвертировать между этими примитивными типами и соответствующим классом-оболочкой. Это называется бокс и распаковка. Когда вы пишете

Integer in = (Integer)y; //this is unnecessary casting

или

Integer in = new Integer(y); //create a new instance of Integer class

Вы в основном конвертируете между примитивным типом и классом-оболочкой. Но у Java есть функция Auto Boxing and Unboxing Там, где Java будет делать эти кастинга для вас. Просто напишите

int iPrimi = 20;
Integer iWrapper = iPrimi; //Autoboxing 
int iPrimi2 = iWrapper; //Auto unboxing

Автобоксинг и Unboxing снижают производительность. Примитивы кажутся в 2-3 раза быстрее, чем эквивалент Integer. Поэтому не используйте их, если вам это не нужно.