Різниця між parseInt () та valueOf () у Java?


443

Чим parseInt()відрізняється від valueOf()?

Вони , здається, робити те ж саме для мене (також стосується parseFloat(), parseDouble(), і parseLong()т.д., як вони відрізняються від Long.valueOf(string)?

Крім того, який із них є кращим і частіше використовується конвенцією?

Відповіді:


411

Ну, API для Integer.valueOf(String)насправді говорить про те, що Stringінтерпретується точно так, як ніби це було дано Integer.parseInt(String). Однак valueOf(String)повертає об'єкт, тоді як повертає примітив .new Integer()parseInt(String)int

Якщо ви хочете насолоджуватися потенційними перевагами кешування Integer.valueOf(int), ви також можете скористатися цим вікном:

Integer k = Integer.valueOf(Integer.parseInt("123"))

Тепер, якщо то , що ви хочете , це об'єкт , а не примітивний, а потім з допомогою valueOf(String)може бути більш привабливим , ніж створення нового об'єкта з parseInt(String)бо колишній послідовно присутній через Integer, Long, Doubleі т.д.


8
Чи є різниця в продуктивності чи пам’яті між двома підходами?
Логан

90
Integer.valueOf(Integer.parseInt("123"))не має переваг по порівнянні з Integer.valueOf("123")або в Integer.valueOf(123)сторону від расточітельствуя циклів і розмір вашої програми.
Томас Едінг

9
Існує відмінність - новий Об'єкт (потенційно), виділений valueOf, має накладні витрати (пам'ять для об'єкта, обробка, GC), тоді як звичайний int надзвичайно "легкий". (Для найпоширеніших значень ви знайдете посилання на вже існуючі об’єкти, що допомагає крихітно.)
foo

14
Integer.valueOf(String)робить точно так само, як і кешування Integer.valueOf(int). Насправді він реалізований як Integer.valueOf(Integer.parseInt(…))
Holger

11
@Khez Це неможливо повернути примітив int. Підпис говорить, що він повертає Integer, і саме це робить. Ця відповідь також частково неправильна, коли говорить, що повертає "нове" Integer. Це не те, що написано в Javadoc. Повернути кеш можна безкоштовно Integer.
Маркіз Лорн

73

З цього форуму :

parseInt()повертає примітивний цілочисельний тип ( int ), завдяки чому valueOfповертає java.lang.Integer , який є об'єктом, що представляє ціле число. Існують обставини, коли ви можете захотіти об'єкт Integer замість примітивного типу.

Звичайно, ще одна очевидна відмінність полягає в тому, що intValue - це метод примірника, за допомогою якого parseInt є статичним методом.


9
Варто зазначити: версії valueOf також використовуватимуть внутрішній пул посилань, щоб повернути об’єкт SAME для заданого значення, а не лише інший екземпляр з тим же внутрішнім значенням. Це означає, що дані два Лонги повернулися таким чином, a.equals (b) == true і a == b - це правда
basszero

Як було доведено далі, ви правильні для String версій, я думав про примітивні версії. Long.valueOf (5) завжди буде повертати один і той же об'єкт. Версії рядків повертають нові об'єкти, примітивні версії повертають ті самі об’єкти
basszero

1
@bassezero. Також цей пул має обмеження. Я думаю, це було від -127 до 127.
OscarRyz

1
Розмір посилального пулу - справжній приклад деталі реалізації; він навіть може бути збільшений в розмірі у випуску патча, і ви ніколи не повинні покладатися на нього ні на що.
Стипендіати Доналу

@OscarRyz Насправді це від -128 до 127. Зауважте, що JVM пропонує параметр для встановлення найвищої межі вище для кешу. Однак ви не можете переосмислити нижню межу: stackoverflow.com/questions/29633158/…
Жан-Франсуа Савард

36
Integer.valueOf(s)

подібний до

new Integer(Integer.parseInt(s))

Різниця полягає у valueOf()поверненні Integerта parseInt()поверненні int(примітивний тип). Також зауважте, що valueOf()можна повернути кешований Integerекземпляр, що може призвести до заплутаних результатів, якщо результат ==тестів здається переривчасто правильним. Перед автобоксингом могла бути різниця у зручності, після java 1.5 це насправді не має значення.

Більше того, Integer.parseInt(s)може приймати і примітивний тип даних.


4
valueOf () може повернути один і той же об'єкт для послідовних викликів з тим самим аргументом (і потрібно для аргументів між -128 і 127 включно). новий Integer () завжди створюватиме новий об'єкт.
Адам Розенфілд

Який із них використовується частіше? Який із них я повинен використовувати найбільше?
Клацніть Upvote

3
Якщо вам потрібен int, використовуйте parseInt (), якщо вам потрібен Integer, використовуйте valueOf ()
matt b

@Joan d Silva з вашого останнього рядка, я думаю, що Integer.parseInt (и) може сприймати лише як рядок, тоді як Integer.ValueOf (s) може приймати як int, так і рядок як вхідний аргумент
Pratik

14

Подивіться на джерела Java: valueOfвикористовує parseInt:

/**
 * Parses the specified string as a signed decimal integer value.
 *
 * @param string
 *            the string representation of an integer value.
 * @return an {@code Integer} instance containing the integer value
 *         represented by {@code string}.
 * @throws NumberFormatException
 *             if {@code string} cannot be parsed as an integer value.
 * @see #parseInt(String)
 */
public static Integer valueOf(String string) throws NumberFormatException {
    return valueOf(parseInt(string));
}

parseInt повертає int

/**
 * Parses the specified string as a signed decimal integer value. The ASCII
 * character \u002d ('-') is recognized as the minus sign.
 *
 * @param string
 *            the string representation of an integer value.
 * @return the primitive integer value represented by {@code string}.
 * @throws NumberFormatException
 *             if {@code string} cannot be parsed as an integer value.
 */
public static int parseInt(String string) throws NumberFormatException {
    return parseInt(string, 10);
}

6

Integer.parseInt може просто повернути Int як рідний тип.

Integer.valueOf, можливо, потрібно буде виділити об'єкт Integer, якщо це ціле число не буде одним із попередньо виділених. Це коштує дорожче.

Якщо вам потрібен лише рідний тип, використовуйте parseInt. Якщо вам потрібен об’єкт, використовуйте valueOf.

Крім того, через таке потенційне розподіл, автобоксинг насправді не є гарною справою в усіх відношеннях. Це може уповільнити справи.


1

Варіанти синтаксичного аналізу * повертають примітивні типи, а версії valueOf повертають об'єкти. Я вважаю, що версії valueOf також використовуватимуть внутрішній контрольний пул для повернення об'єкта SAME для заданого значення, а не лише іншого екземпляра з тим же внутрішнім значенням.


Власне, не зовсім правда. Спочатку я так думав, але Javadocs для Integer.valueOf (String) чітко стверджує, що він еквівалентний новому Integer (Integer.parseInt (String)). Integer.valueOf (int) дійсно кешує.
Майкл Майерс

Ви правильні для String версій, я думав про примітивні версії. Long.valueOf (5) завжди буде повертати один і той же об'єкт.
basszero

1

Тому що ви, можливо, використовуєте jdk1.5 + і там він автоматично перетворюється на int. Тож у вашому коді його перший повертається цілий, а потім автоматично перетворюється на int.

ваш код такий же, як

int abc = new Integer(123);

0

Якщо ви перевірте клас Integer, ви знайдете метод value parseInt цього значення. Велика різниця полягає в кешуванні, коли ви викликаєте valueof API. Це кеш, якщо значення становить від -128 до 127. Для отримання додаткової інформації знайдіть нижче посилання

http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html


0

public static Integer valueOf (String s)

  1. Аргумент інтерпретується як відображення підписаного десяткового цілого числа, точно так, як якщо б аргумент був наданий методу parseInt (java.lang.String).
  2. Результатом є об'єкт Integer, який представляє ціле значення, вказане рядком.

  3. Іншими словами, цей метод повертає об'єкт Integer, рівний значенню: new Integer (Integer.parseInt (s))


0
  • valueOf - перетворюється в клас Wrapper
  • parseInt - перетворює на примітивний тип

Integer.parseInt приймає тільки рядок і повертає примітивний цілочисельний тип (int).

   public static int parseInt(String s) throws NumberFormatException {
        return parseInt(s,10);
    }

Iteger.valueOf приймати int та String. Якщо значення є String, valueOf перетворить його в простий int за допомогою parseInt і поверне новий Integer, якщо вхід менше -128 або більше 127. Якщо вхід знаходиться в діапазоні (-128 - 127), воно завжди повертає об'єкти Integer з внутрішній IntegerCache. Клас Integer підтримує внутрішній статичний клас IntegerCache, який діє як кеш і містить цілі об'єкти від -128 до 127, і тому, коли ми намагаємося отримати цілий об'єкт для 127 (наприклад), ми завжди отримуємо той самий об'єкт.

Iteger.valueOf(200)дасть новий Integer від 200. Це схоже new Integer(200) Iteger.valueOf(127)на те, що Integer = 127;

Якщо ви не хочете конвертувати String у цілісне використання Iteger.valueOf.

Якщо ви не хочете перетворити String в просте використання int Integer.parseInt. Це працює швидше.

  public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

  public static Integer valueOf(String s) throws NumberFormatException {
        return Integer.valueOf(parseInt(s, 10));
  }

  private static class IntegerCache {
      static final int low = -128;
      static final int high;
      static final Integer cache[];

    static {
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue =
            sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
            try {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            } catch( NumberFormatException nfe) {
                // If the property cannot be parsed into an int, ignore it.
            }
        }
        high = h;

        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);

        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }

    private IntegerCache() {}
  }

І порівнюючи Integer.valueOf (127) == Integer.valueOf (127) повернути істину

Integer a = 127; // Compiler converts this line to Integer a = Integer.valueOf(127);
Integer b = 127; // Compiler converts this line to Integer b = Integer.valueOf(127);
a == b; // return true 

Тому що він бере об'єкти Integer з однаковими посиланнями з кеша.

Але Integer.valueOf (128) == Integer.valueOf (128) помилково, оскільки 128 знаходиться поза діапазоном IntegerCache, і він повертає новий Integer, тому об’єкти матимуть різні посилання.


Будь ласка, не зловживайте сміливим форматуванням: це погіршує читабельність вашої публікації.
Зої

-2
  1. У випадку ValueOf -> це створює об'єкт Integer. не примітивний тип і не статичний метод.
  2. У випадку ParseInt.ParseFloat -> він повертає відповідний примітивний тип. і є статичним методом.

Ми повинні використовувати будь-яку, залежно від потреби. У разі ValueOf, як це екземпляр об'єкта. він буде споживати більше ресурсів, якщо нам потрібно лише значення деякого тексту, тоді ми повинні використовувати parseInt, parseFloat і т.д.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.