Различия между новым Integer (123), Integer.valueOf (123) и просто 123 - PullRequest
27 голосов
/ 27 января 2012

Недавно я видел код (Java), подобный этому:

myMethod(new Integer(123));

В настоящее время я выполняю рефакторинг некоторого кода, и в инструменте Sonar есть подсказка, что использование sth более удобно для памяти:

myMethod(Integer.valueOf(123));

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

myMethod(123);

Я мог бы понять это, если бы передал переменную методу, ножестко закодированный int?Или если будет Long / Double и т.д., и я хочу Long представление числа.Но целое число?

Ответы [ 5 ]

32 голосов
/ 27 января 2012

new Integer(123) создаст новый экземпляр Object для каждого вызова.

Согласно javadoc , Integer.valueOf(123) имеет различие, которое кэширует объекты ... так что вы можете (или не можете) получить один и тот же Object, если вызовете его более одного раза.

Например, следующий код:

   public static void main(String[] args) {

        Integer a = new Integer(1);
        Integer b = new Integer(1);

        System.out.println("a==b? " + (a==b));

        Integer c = Integer.valueOf(1);
        Integer d = Integer.valueOf(1);

        System.out.println("c==d? " + (c==d));

    }

Имеет следующий вывод:

a==b? false
c==d? true

Что касается использования значения int, то вы используете тип примитива (учитывая, что ваш метод также использует тип примитива в своей сигнатуре) - он будет использовать немного меньше памяти и может быть быстрее, но вы не будете элем например, чтобы добавить его в коллекции.

Также взгляните на Java AutoBoxing , если подпись вашего метода использует Integer - при его использовании JVM автоматически вызовет Integer.valueOf() для вас (следовательно, с использованием кеша).

8 голосов
/ 27 января 2012

public static Integer valueOf(int i)

Возвращает экземпляр типа Integer, представляющий указанное значение типа int.Если новый экземпляр Integer не требуется, этот метод обычно следует использовать в предпочтении перед конструктором Integer (int), поскольку этот метод может значительно повысить производительность пространства и времени за счет кэширования часто запрашиваемых значений.

Параметры:
i - значение типа int.
Возвращает:
a Целочисленный экземпляр, представляющий i.
Так как:
1,5

см.http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Integer.html#valueOf%28int%29

Этот вариант valueOf был добавлен в JDK 5 к Byte, Short, Integer и Long (он уже существовал в тривиальном случае в Boolean начиная с JDK 1.4).Все это, конечно, неизменяемые объекты в Java.Раньше считалось, что если вам нужен объект Integer из int, вы создадите новое Integer.Но в JDK 5+, вы действительно должны использовать valueOf, потому что Integer теперь кэширует объекты Integer между -128 и 127 и может возвращать вам один и тот же объект Integer (0) каждый раз вместо того, чтобы тратить конструкцию объекта на совершенно новыйидентичный объект Integer.

private static class IntegerCache {
private IntegerCache(){}

static final Integer cache[] = new Integer[-(-128) + 127 + 1];

static {
    for(int i = 0; i < cache.length; i++)
    cache[i] = new Integer(i - 128);
}
}

public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) { // must cache
    return IntegerCache.cache[i + offset];
}
    return new Integer(i);
}

см. Почему ВЫ должны использовать Integer.valueOf (int)

РЕДАКТИРОВАТЬ

автобокс и создание объектов:

Важным моментом, который мы должны учитывать, является то, что автобокс не уменьшает создание объектов, но уменьшает сложность кода.Хорошее эмпирическое правило - использовать примитивные типы, в которых нет необходимости для объектов, по двум причинам:

Примитивные типы не будут медленнее, чем их соответствующие типы-оболочки, и могут быть намного быстрее.Может быть неожиданное поведение, связанное с == (сравнить ссылки) и .equals () (сравнить значения).

Обычно, когда примитивные типы помещаются в упаковочные типы, JVM выделяет память исоздает новый объект.Но для некоторых особых случаев JVM повторно использует один и тот же объект.

Ниже приведен список примитивов, хранящихся как неизменяемые объекты:

  • логические значения true и false

  • Все байтовые значения

  • короткие значения от -128 до 127

  • int значения от -128 до127

  • символ в диапазоне от \ u0000 до \ u007F

см. http://today.java.net/pub/a/today/2005/03/24/autoboxing.html#performance_issue

1 голос
/ 27 января 2012

только диапазон от -128 до +127 реализует в кэше.

Integer a = new Integer(1);
 Integer b = new Integer(1);

 System.out.println("a==b? " + (a==b));

 Integer c = Integer.valueOf(127);
 Integer d = Integer.valueOf(127);

 System.out.println("c==d? " + (c==d)); 

 Integer e = Integer.valueOf(128);
 Integer f = Integer.valueOf(128);

 System.out.println("e==f? " + (e==f)); 

См. Эту спецификацию Java:

http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.7

в JDK 5+, выдолжен действительно использовать valueOf, потому что Integer теперь кэширует объекты Integer между -128 и 127 и может каждый раз возвращать один и тот же объект Integer (0) вместо того, чтобы тратить конструкцию объекта на совершенно новый идентичный объект Integer.

1 голос
/ 27 января 2012

Требуется ли вашему методу int или Integer?

new Integer(int) и Integer.valueOf(int), оба возвращают Integer объекты, но valueOf следует отдать предпочтение, так как он более эффективен, посколькуон возвращает кешированные объекты.Если ваш метод требует Integer, вы должны использовать Integer.valueOf.

Если ваш метод требует int, вы должны использовать int (например, 123).

Тем не менее, нет необходимости строго сопоставлять типы таким образом из-за autoboxing , который автоматически преобразует int в Integer и наоборот, когда типы не совпадают.Это позволяет вам передавать int в метод, требующий Integer, и Integer в метод, требующий int.Но имейте в виду, что с автобоксом связаны затраты производительности.Наиболее распространенный пример использования автобокса - это если вы хотите хранить примитивы в коллекции.

1 голос
/ 27 января 2012

int является типом примитива, а не объектом.

new Integer(123) и Integer.valueOf(123) оба возвращают Integer объект, представляющий значение 123. Согласно javadoc для Integer.valueOf():

Возвращает экземпляр Integer, представляющий указанное значение типа int.Если новый экземпляр Integer не требуется, этот метод обычно следует использовать в предпочтении перед конструктором Integer (int), поскольку этот метод может значительно повысить производительность пространства и времени за счет кэширования часто запрашиваемых значений.

...