Różni się między parseInt () i valueOf () w java?

443

Czym się parseInt()różni valueOf()?

Pojawiają się one robić dokładnie to samo do mnie (również idzie do parseFloat(), parseDouble(), parseLong()etc, w jaki sposób są one różne od Long.valueOf(string)?

Który z nich jest preferowany i częściej wykorzystywany w konwencji?

Kliknij opcję Upvote
źródło

Odpowiedzi:

411

Cóż, API dla Integer.valueOf(String)rzeczywiście mówi, że Stringjest interpretowany dokładnie tak, jakby został przekazany Integer.parseInt(String). Jednak valueOf(String)zwraca obiekt, natomiast zwraca prymitywnych .new Integer()parseInt(String)int

Jeśli chcesz czerpać korzyści z potencjalnego buforowania Integer.valueOf(int), możesz również skorzystać z tego narzędzia do usuwania oczu:

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

Teraz, jeśli to, co chcesz, jest przedmiotem, a nie prymitywne, a następnie przy użyciu valueOf(String)mogą być bardziej atrakcyjne niż tworzenia nowego obiektu z parseInt(String)ponieważ ta pierwsza jest stale obecny w poprzek Integer, Long, Double, itd.

Zach Scrivena
źródło
8
Czy istnieje jakaś różnica w wydajności lub pamięci między tymi dwoma podejściami?
Logan
90
Integer.valueOf(Integer.parseInt("123"))nie ma korzyści Integer.valueOf("123")ani Integer.valueOf(123)marnowania cykli, ani rozmiaru twojego programu.
Thomas Eding,
9
Jest różnica - nowy Object (potencjalnie) przydzielony przez valueOf ma narzut (pamięć dla obiektu, obsługa, GC), podczas gdy zwykły int jest wyjątkowo „lekki”. (W przypadku najczęstszych wartości otrzymasz odniesienia do wcześniej istniejących Obiektów, co trochę pomaga.)
foo
14
Integer.valueOf(String)wykonuje dokładnie takie samo buforowanie jak Integer.valueOf(int). W rzeczywistości jest zaimplementowany jako Integer.valueOf(Integer.parseInt(…))
Holger
11
@Khez Nie można zwrócić prymitywu int. Podpis mówi, że zwraca Integeri to jest dokładnie to, co robi. Ta odpowiedź jest również częściowo niepoprawna, gdy mówi, że zwraca „nowy” Integer. Tak nie jest napisane w Javadoc. Zwrot pamięci podręcznej jest bezpłatny Integer.
Markiz Lorne
73

Z tego forum :

parseInt()zwraca pierwotny typ liczb całkowitych ( int ), przy czym valueOfzwraca java.lang.Integer , który jest obiektem reprezentatywnym dla liczby całkowitej. Są okoliczności, w których możesz chcieć obiektu typu Integer zamiast typu pierwotnego.

Oczywiście inną oczywistą różnicą jest to, że intValue jest metodą instancji, w której parseInt jest metodą statyczną.

Michael Haren
źródło
9
Warto wspomnieć: wersje valueOf będą również korzystać z wewnętrznej puli referencyjnej, aby zwrócić obiekt SAME dla danej wartości, a nie tylko innej instancji o tej samej wartości wewnętrznej. Oznacza to, że biorąc pod uwagę dwa Longs zwrócone w ten sposób, a.equals (b) == true i a == b jest true
basszero
Jak udowodniono dalej, masz rację dla wersji String, myślałem o prymitywnych wersjach. Long.valueOf (5) zawsze zwróci ten sam obiekt. Wersje łańcuchowe zwracają nowe obiekty, wersje pierwotne zwracają te same obiekty
basszero
1
@bassezero. Ponadto pula ma limit. Myślę, że było to -127 do 127.
OscarRyz
1
Rozmiar puli referencyjnej jest prawdziwym przykładem szczegółów implementacji; można go nawet zwiększyć w wydaniu łatki i nigdy nie powinieneś na nim polegać .
Donal Fellows,
@OscarRyz Właściwie jest to -128 do 127. Zauważ, że JVM oferuje parametr ustawiający najwyższą granicę wyżej dla pamięci podręcznej. Nie można jednak ponownie zdefiniować najniższej granicy: stackoverflow.com/questions/29633158/...
Jean-François Savard
36
Integer.valueOf(s)

jest podobne do

new Integer(Integer.parseInt(s))

Różnica polega na valueOf()zwracaniu an Integeri parseInt()zwracaniu an int(typ pierwotny). Zauważ też, że valueOf()może zwrócić Integerinstancję z pamięci podręcznej , co może powodować mylące wyniki, gdy wyniki ==testów wydają się sporadycznie poprawne. Przed autoboxingiem może być różnica w wygodzie, po Java 1.5 nie ma to tak naprawdę znaczenia.

Ponadto Integer.parseInt(s)może również przyjmować prymitywny typ danych.

Joao da Silva
źródło
4
valueOf () może zwrócić ten sam obiekt dla kolejnych wywołań z tym samym argumentem (i jest wymagany w przypadku argumentów od -128 do 127 włącznie). new Integer () zawsze tworzy nowy obiekt.
Adam Rosenfield
Który jest używany częściej? Którego powinienem użyć najczęściej?
Kliknij Upvote
3
Jeśli potrzebujesz wartości int, użyj parseInt (), jeśli potrzebujesz liczby całkowitej, użyj valueOf ()
matt b
@Joan d Silva z twojego ostatniego wiersza, myślę, że Integer.parseInt (s) może przyjmować tylko jako ciąg, podczas gdy Integer.ValueOf (s) może przyjmować zarówno int, jak i ciąg jako argument wejściowy
Pratik
14

Spójrz na źródła Java: valueOfużywa 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 zwroty 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);
}
Paul Verest
źródło
6

Integer.parseInt może po prostu zwrócić int jako typ macierzysty.

Integer.valueOf może faktycznie wymagać przydzielenia obiektu Integer, chyba że ta liczba całkowita przypadkowo będzie jedną z wstępnie przydzielonych. To kosztuje więcej.

Jeśli potrzebujesz tylko rodzimego typu, użyj parseInt. Jeśli potrzebujesz obiektu, użyj valueOf.

Ponadto, z powodu tego potencjalnego przydziału, autoboxing nie jest tak naprawdę dobrą rzeczą pod każdym względem. Może spowolnić rzeczy.

iny
źródło
1

Warianty parsowania * zwracają typy pierwotne, a wersje valueOf zwracają obiekty. Wierzę, że wersje valueOf będą również korzystać z wewnętrznej puli referencyjnej, aby zwrócić obiekt SAME dla danej wartości, a nie tylko innej instancji o tej samej wartości wewnętrznej.

basszero
źródło
Właściwie nie do końca prawda. Na początku tak myślałem, ale Javadocs dla Integer.valueOf (String) wyraźnie stwierdzają, że jest to odpowiednik nowej liczby całkowitej (Integer.parseInt (String)). Jednak Integer.valueOf (int) faktycznie buforuje.
Michael Myers
Masz rację dla wersji String, myślałem o prymitywnych wersjach. Long.valueOf (5) zawsze zwróci ten sam obiekt.
basszero
1

Ponieważ możesz używać jdk1.5 + i tam następuje automatyczna konwersja na int. Więc w kodzie najpierw zwracana jest liczba całkowita, a następnie automatycznie konwertowana na int.

twój kod jest taki sam jak

int abc = new Integer(123);
ZNISZCZYĆ
źródło
0

Jeśli zaznaczysz klasę całkowitą, znajdziesz wartość metody wywołania parseInt. Dużą różnicą jest buforowanie podczas wywoływania wartości API. Buforuje, jeśli wartość mieści się w przedziale od -128 do 127. Więcej informacji można znaleźć pod linkiem

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

TheGraduateGuy
źródło
0

public static static Integer valueOf (String s)

  1. Argument jest interpretowany jako reprezentujący liczbę całkowitą ze znakiem dziesiętnym, dokładnie tak, jakby argument został podany metodzie parseInt (java.lang.String).
  2. Wynikiem jest obiekt typu Integer, który reprezentuje wartość całkowitą określoną przez ciąg.

  3. Innymi słowy, ta metoda zwraca obiekt typu Integer równy wartości: new Integer (Integer.parseInt (s))

shuaihanhungry
źródło
0
  • valueOf - konwertuje do klasy Wrapper
  • parseInt - konwertuje na typ pierwotny

Integer.parseInt akceptuje tylko ciąg znaków i zwraca pierwotną liczbę całkowitą typu int (int).

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

Iteger.valueOf accept int i String. Jeśli wartością jest String, wartośćOf przekształca ją na zwykłą liczbę int za pomocą parseInt i zwraca nową liczbę całkowitą, jeśli wartość wejściowa jest mniejsza niż -128 lub większa niż 127. Jeśli wartość wejściowa jest w zakresie (-128 - 127), zawsze zwraca obiekty Integer z wewnętrzna IntegerCache. Klasa całkowita utrzymuje wewnętrzną statyczną klasę IntegerCache, która działa jako pamięć podręczna i przechowuje obiekty całkowite od -128 do 127 i dlatego, gdy próbujemy uzyskać obiekt całkowity dla 127 (na przykład), zawsze otrzymujemy ten sam obiekt.

Iteger.valueOf(200)da nową liczbę całkowitą od 200. To jest tak new Integer(200) Iteger.valueOf(127)samo jak Integer = 127;

Jeśli nie chcesz konwertować ciągu znaków na liczbę całkowitą, użyj Iteger.valueOf.

Jeśli nie chcesz konwertować ciągu znaków na prosty int use Integer.parseInt. Działa szybciej.

  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() {}
  }

I porównanie Integer.valueOf (127) == Integer.valueOf (127) zwraca true

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 

Ponieważ pobiera obiekty Integer z tymi samymi odwołaniami z pamięci podręcznej.

Ale Integer.valueOf (128) == Integer.valueOf (128) jest fałszem, ponieważ 128 jest poza zakresem IntegerCache i zwraca nową liczbę całkowitą, więc obiekty będą miały różne odwołania.

Andrij
źródło
Nie nadużywaj pogrubionego formatowania: zmniejsza to czytelność Twojego postu.
Zoe
-2
  1. W przypadku ValueOf -> tworzy obiekt typu Integer. nie typ pierwotny, a nie metoda statyczna.
  2. W przypadku ParseInt.ParseFloat -> zwraca odpowiedni typ pierwotny. i jest metodą statyczną.

Powinniśmy użyć każdego w zależności od naszych potrzeb. W przypadku ValueOf, ponieważ tworzy on obiekt. zużyje więcej zasobów, jeśli potrzebujemy tylko wartości jakiegoś tekstu, wówczas powinniśmy użyć parseInt, parseFloat itp.


źródło