Kiedy używać prymitywnych i kiedy typów referencyjnych w Javie

W jakim przypadku należy użyć typów prymitywnych (int) lub typów referencyjnych (Integer)?

To pytanie wzbudziło moją ciekawość.
Author: Community, 2010-03-24

10 answers

W którym przypadku należy użyć primitive typy (int) lub typy referencyjne (Integer)?

Jako zasada, będę używał prymitywu (takiego jak int), chyba że będę musiał użyć klasy, która owija prymityw.

Jednym z przypadków było użycie klasy wrapper, takiej jak Integer jest w przypadku użycia generics , ponieważ Java nie obsługuje używania typów prymitywnych jako parametrów typu:

List<int> intList = new ArrayList<int>();               // Not allowed.
List<Integer> integerList = new ArrayList<Integer>();   // Allowed.

I w wielu przypadkach skorzystam z autoboxing i unboxing , więc nie muszę jawnie wykonywać konwersji z primitives do jego klasy wrapper i odwrotnie:

// Autoboxing will turn "1", "2", "3" into Integers from ints.
List<Integer> numbers = Arrays.asList(1, 2, 3); 

int sum = 0;

// Integers from the "numbers" List is unboxed into ints.
for (int number : numbers) {
  sum += number;
}

Ponadto, jako dodatkowa uwaga, podczas konwersji z primitives do obiektów klasy wrapper, a unikalne instancje obiektów nie są konieczne, użyj metody valueOf dostarczonej przez metodę wrapper, ponieważ wykonuje buforowanie i zwraca tę samą instancję dla określonej wartości, zmniejszając liczbę obiektów, które są utworzony:

Integer i1 = Integer.valueOf(1);   // Prefer this.
Integer i2 = new Integer(1);       // Avoid if not necessary.

Aby uzyskać więcej informacji na temat metod valueOf, specyfikacja API dla Integer.valueOf metoda może służyć jako odniesienie do tego, jak te metody będą się zachowywać w klasach wrappera dla prymitywów.

 22
Author: coobird,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-24 16:32:12

To naprawdę zależy od kontekstu. Najpierw preferuj prymitywne, ponieważ jest bardziej intuicyjne i ma mniej kosztów. Jeśli nie jest to możliwe z powodów generycznych/autoboxingowych lub jeśli chcesz, aby było to nullable, wybierz typ wrappera (typ złożony, jak go nazywasz).

 9
Author: BalusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-24 15:40:25

Ogólne zasady, których przestrzegam podczas tworzenia API, można podsumować w następujący sposób:

  1. Jeśli metoda musi zwrócić wartość, użyj prymitywnego typu
  2. Jeśli metoda może nie zawsze mieć zastosowanie (np.: getRadioId(...) na obiekcie, w którym takie ID może nie istnieć), następnie zwraca liczbę całkowitą i określa w JavaDocs, że metoda zwróci null w niektórych przypadkach.

Na # 2, uważaj na NPEs podczas autoboxingu. Jeśli masz metodę zdefiniowaną jako:

public Integer getValue();

Oraz następnie nazwij to w następujący sposób:

int myValue = getValue();

W przypadku, gdy getValue () zwraca null, otrzymasz NPE bez oczywistej przyczyny.

 3
Author: Jason Nichols,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-24 16:19:33

Moja zasada brzmi: używaj pudełkowych prymitywów tylko wtedy, gdy jest to konieczne, aby uzyskać kod do kompilacji. Jedyne miejsca w kodzie, w których powinny pojawić się nazwy prymitywnych klas opakowujących, to parametry typu generycznego i statyczne wywołania metod:

List<Integer> intList = new ArrayList<Integer>();

int n = Integer.parseInt("123");

Taką radę dałbym nowym programistom Javy. Gdy się więcej dowiedzą, napotkają sytuacje, w których muszą być bardziej spostrzegawczy, jak w przypadku map lub baz danych, ale do tego czasu powinni również mieć lepsze zrozumienie różnicy między prymitywami a prymitywami z pudełka.

Autoboxing kusi nas do przekonania, że int i Integer (na przykład) są wymienne, ale to pułapka. Jeśli wymieszasz te dwa rodzaje wartości bez rozróżnienia, możesz porównać dwie wartości całkowite z {[3] } lub spróbować rozpakować null, nie zdając sobie z tego sprawy. Powstałe błędy mogą być przerywane i trudne do wyśledzenia.

Nie pomaga to, że porównywanie pudełkowych prymitywów z == czasami działa tak, jakby robił porównanie wartości. Jest to iluzja spowodowana faktem, że wartości w określonym zakresie są automatycznie buforowane w procesie autoboxingu. Jest to ten sam problem, jaki zawsze mieliśmy z wartościami łańcuchowymi: porównywanie ich z == czasami "działa", ponieważ porównujesz dwa odwołania do tego samego, buforowanego obiektu.

Kiedy mamy do czynienia ze strunami, możemy po prostu powiedzieć n00bs, aby nigdy nie porównywali ich z ==, jak robiliśmy cały czas. Ale porównywanie prymitywów z == jest całkowicie poprawne; sztuczka (dzięki autoboxingowi) polega na upewnieniu się, że wartości naprawdę są prymitywami. Kompilator pozwoli nam teraz zadeklarować zmienną jako Integer i użyć jej tak, jakby była int; oznacza to, że musimy ćwiczyć większy poziom dyscypliny i traktować ją jako błąd, gdy ktoś robi to bez ważnego powodu.

 3
Author: Alan Moore,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-25 04:24:38

Ponieważ Java robi coś, co nazywa się auto-boxing i auto-unboxing , powinieneś używać prymitywnego typu int w większości przypadków ze względu na mniejsze koszty.

Jedyny raz, kiedy absolutnie potrzebujesz użyć Integer, jest w generikach.

List<int> list; // won't compile
List<Integer> list; // correct
 2
Author: jjnguy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-24 15:41:18

Zamiast nazywać je "typami złożonymi", najlepiej byłoby pomyśleć o liczbie całkowitej, podwójnej itp. jako "klasy", oraz int, double, itp. jako "prymitywni".

Jeśli robisz dowolny rodzaj zaawansowanej matematyki, reprezentacja liczbowa oparta na klasach, taka jak liczba całkowita i podwójna, będzie uciążliwa i spowolni cię - wiele operacji matematycznych można wykonać tylko z prymitywami.

Z drugiej strony, jeśli próbujesz umieścić swoje liczby w kolekcjach, takich jak listy i mapy, zbiory te mogą zawierają tylko obiekty - i dlatego musisz używać (lub konwertować na) klas takich jak Integer i Double.

Osobiście używam primitives, gdy tylko mogę się z tym wywinąć, i konwertuję na reprezentacje klasy, takie jak Integer, tylko wtedy, gdy nadszedł czas na wejście lub wyjście, a transport wymaga tych reprezentacji.

Jednak, jeśli nie robisz żadnej matematyki, a zamiast tego po prostu przekazujesz wartości prosto przez KOD, możesz zaoszczędzić sobie kłopotów, zajmując się Wyłącznie form opartych na klasach (np. Integer).

 1
Author: Glenn Barnett,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-24 15:46:03

Myślę, że nie ma żadnej zasady jako takiej. Wybrałbym typy nad prymitywami (Integer nad int), gdy piszę podpisy metod, Mapy, Kolekcje, Obiekty danych, które są przekazywane. Jako taki nadal chciałbym używać Integer zamiast int nawet wewnątrz metod itp. Ale jeśli uważasz, że jest to zbyt duży problem (aby wpisać dodatkowy "eger"), to jest w porządku, aby używać ints dla zmiennych lokalnych.

 0
Author: Kannan Ekanath,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-24 15:41:40

Jeśli chcesz ustawić sesję, musisz użyć obiektu typu Integer,Boolean, String w servletach. Jeśli chcesz użyć wartości, możesz użyć typów prymitywnych. Obiekty mogą być null, ale prymitywy nie. A jeśli chcesz porównać typy dla prymitywów użyj ==, ale użyj obiektów .równa się, ponieważ w porównywaniu obiektów = = nie wygląda na wartości, wygląda, jeśli są to te same obiekty. A używanie prymitywów przyspiesza kod.

 0
Author: user300943,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-24 15:54:56

Jeden przypadek, w którym Integer może być preferowany, jest wtedy, gdy pracujesz z bazą danych, w której wpisy liczbowe mogą być null, ponieważ nie możesz reprezentować wartości null za pomocą int.

Ale oczywiście, jeśli robisz prostą matematykę, to int byłoby lepiej, jak inni wspominali, ze względu na intuicyjność i mniej kosztów ogólnych.

 0
Author: FromCanada,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-24 15:55:04

Myślę, że to trochę za późno, ale chciałem dodać swoją opinię na wszelki wypadek.

W niektórych scenariuszach wymagane jest użycie wrapperów, ponieważ brak wartości różni się od wartości domyślnej.

Przykład, w przypadku jednego projektu, nad którym pracowałem, było pole na ekranie, w którym użytkownik może wprowadzić podwójną wartość, wymóg biznesowy wyraźnie wspomniał, że jeśli użytkownik wprowadzi 0, znaczenie różni się od nie wprowadzania wartości i pozostawienia pola pustego, a ta różnica będzie dokonaj wpływu później w innym module. tak więc w tym scenariuszu musieliśmy użyć podwójnego obiektu, ponieważ nie mogę reprezentować braku wartości za pomocą primitive; ponieważ primitive będzie domyślnie 0, co było poprawnym wejściem dla pola.

 0
Author: ahmad alzamer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-06 23:49:11