2013-01-20 25 views
10

Tylko próbując zrozumieć auto boks, który robię oprócz jednej rzeczy:klas Wrapper - dlaczego literały całkowite fail za długo, ale pracują dla czegoś mniejszego

Short s = 250; 
Long l = 250; 

Przypisanie do Long l zawiedzie. Oczekuję, że to dlatego, że nie można rozszerzyć tego pola (tzn. Próbuje rozszerzyć wartość 250 na long, a następnie ustawić to, czego nie może zrobić).

Działa jednak przypisanie do Short s. Co się dzieje, żeby to dobrze? Zakładałem, że nadal boksuje i dokonuje jakiejś konwersji. Ale jeśli to jest przypadek, wiedząc, że 250 pasuje do short, dlaczego nie wie, że 250 zmieści się w 250 zmieści się w ?

+1

Auto-boksowanie jest złe [Tylko opinia]. W moich prywatnych projektach i w firmie, w której pracuję, traktujemy auto-boxing jako błędy, aby uniknąć jakichkolwiek nieporozumień. – MrSmith42

+1

jak to "zawieść na długo"? – Archer

+0

Z ciekawości, co dzieje się z krótkim, gdy twój literał wynosi 250 litrów? (Offhand Wiem, że podaje długi dosłowny, ale nie jestem pewien, czy istnieje odpowiedni wyraźny krótki tekst) – Charlie

Odpowiedz

11

Normalnie nie można zastosować wiele (ukryte) przeliczanie w przypisania (JLS §5.2 Assignment Conversion):

Przypisanie konwersja następuje, gdy jest przypisana wartość wyrażenia (§15.26) do zmiennej: typ ekspresji musi zostać przekonwertowany na typ zmiennej. Konteksty przypisania umożliwić korzystanie z jednym z następujących:

  • Konwersja tożsamości (§5.1.1)
  • posiadamy poszerzenia prymitywny konwersji (§5.1.2)
  • powiększającej konwersji odniesienia (§ 5.1.5)
  • Konwersja boksu (§5.1.7), po której opcjonalnie następuje poszerzenie konwersji odniesienia
  • konwersja rozpakowywania (§5.1.8) z opcjonalnym rozszerzeniem prymitywnym.

Long l=250; wymaga dwóch konwersji (poszerzenia prymitywny konwersję następnie konwersję boksie), to dlaczego nie skompilować.

Long l=250l; kompiluje, ponieważ wymaga pojedynczej konwersji boksu.

Ale zwężenie konwersji stałej ekspresji jest szczególnym przypadkiem, dlatego Short s=250; kompiluje:

Ponadto, jeśli wyrażenie jest stała wyrażenie (§15.28) typu byte, short, char lub int :

  • Można zastosować zwężającą się konwersję pierwotną, jeśli typem zmiennej jest bajt, short lub char, a wartość wyrażenia stałego jest reprezentowalna w typie zmiennej.
  • Przewężenie prymitywny konwersji następuje konwersja boksu mogą być stosowane, jeżeli typ zmiennej jest:
    • bajtów, a wartość stałej ekspresji się przedstawić w rodzaju bitu.
    • Krótki i wartość wyrażenia stałego jest reprezentowalna w typie short.
    • Znak i wartość wyrażenia stałego można przedstawić w postaci char.
+0

Dziękujemy za wysiłek, który musieliście podjąć w tworzeniu tej odpowiedzi, jest to doceniane. Czy to "specjalny przypadek"? Miałem nadzieję, że istnieje namacalny powód, którego nie rozumiałem, a zatem mogłem się nauczyć, a nie coś, co muszę wyraźnie pamiętać jako wyjątek od reguły. –

+0

@ user1186046: Nie mogę wyobrazić namacalnego powodu dla tego konkretnego przypadku, ale być może mogę to wyjaśnić w następujący sposób: cała koncepcja zawężania konwersji stałych wyrażeń jest szczególnym przypadkiem (ponieważ jest to jedyny rodzaj zwężającego się przekształcenia, który może dzieje się w sposób niejawny), dlatego nie jest zaskoczeniem, że przynosi szczególne przypadki, gdy stosuje się je do poszczególnych części języka. – axtavt

+0

Witaj, powodem tego jest fakt, że robię OCJP, a celem egzaminu nie jest przetestowanie twojej wiedzy o Javie, ale przetestowanie nieistotnych rzeczy, których nie musisz znać, abyś mógł kupić książki egzaminatorów ;) –

0

Idealnie auto zwężenie nie powinno być dozwolone.

Ale ponieważ nie ma bajt/krótkich literały, nie możemy napisać

byte b = 0b; 

i wydaje się głupie

byte b = (byte)0; 

więc auto zwężenie stałej całkowitej jest dozwolone więc możemy napisać

byte b = 0; 

, która jest przenoszona do przypadku autoboxing.

Dla długich/długich, ponieważ istnieją długie literały, jest to mniejszy problem. Mimo to powinno być dozwolone, ponieważ automatyczne poszerzanie liczby całkowitej ze znakiem jest zawsze bezpieczne.