W poniższym przykładzie
int i = -128;
Integer i2 = (Integer) i; // compiles
Integer i3 = (Integer) -128; /*** Doesn't compile ***/
Integer i4 = (Integer) (int) -128; // compiles
Integer i4 = -128; // compiles
Integer i5 = (int) -128; // compiles
Integer i6 = (Integer) (-128); // compiles
Integer i7 = (Integer) 0-128; // compiles
Nie mogę rzucić -128
z (Integer)
ale mogę rzucić (int) -128
.
Zawsze myślałem, że -128
to int
typ i rzucanie go (int)
powinno być zbędne.
Błąd w wierszu z i3
to
cannot find symbol variable Integer
Próbowałem tego z aktualizacją Java 6 29 i aktualizacją Java 7 1.
EDYCJA: Otrzymujesz to samo zachowanie z +128
zamiast -128
. Wydaje się, że jest to zamieszanie między operatorami jednoargumentowymi i binarnymi.
Integer i = -128;
to powinno się jednak skompilować.Integer i3 = (Integer) (-128);
chociaż się zgadza.Expression expected
tam, gdzieInteger
jest.Odpowiedzi:
Kompilator próbuje odjąć
128
od(Integer)
zamiast rzutować-128
doInteger
. Dodaj,()
aby to naprawićWedług BoltClock w komentarzach odlew
int
działa zgodnie z przeznaczeniem, ponieważ jest to słowo zastrzeżone i dlatego nie może być interpretowane jako identyfikator, co ma dla mnie sens.Bringer128 znalazł JLS Reference 15.16 .
Jak widać, rzutowanie na typ pierwotny wymaga dowolnego
UnaryExpression
, podczas gdy rzutowanie na typ referencyjny wymaga plikuUnaryExpressionNotPlusMinus
. Są one zdefiniowane tuż przed CastExpression w JLS 15.15 .źródło
int
jest to słowo kluczowe w Javie, ale nimInteger
nie jest. Ponieważint
jest to słowo kluczowe, nie można go używać jako identyfikatora zmiennej lub klasy, pozostawiając jedyną pozostałą możliwość jako rzutowanie. To by to wyjaśniało.Znalazłem odniesienie do JLS. 15.16 .
Jak widać, rzutowanie na typ pierwotny wymaga dowolnego
UnaryExpression
, podczas gdy rzutowanie na typ referencyjny wymaga plikuUnaryExpressionNotPlusMinus
. Są one zdefiniowane tuż przed CastExpression w JLS 15.15 .Musisz albo zmienić rzutowanie na typ pierwotny:
Lub możesz zmienić wyrażenie po prawej stronie rzutowania na jednoargumentowe wyrażenie inne niż plus-minus:
źródło
Kompilator interpretuje the
-
jako dwuargumentowy operator minus, tj. Próbuje odjąć 128 od innej wymienionej liczbyInteger
, ale nie ma takiej zmiennej w zakresie.To kompiluje:
źródło
(int)
ma znaczenie.Może to mieć związek z analizowaniem składni. Zauważ, że
działa dobrze.
Ogólnie rzecz biorąc, nie należy rzutować na klasę Integer. Wiąże się to z czymś, co nazywa się automatycznym boksowaniem i może powodować drobne błędy w kodzie. Preferowaną metodą robienia tego, co chcesz, jest:
źródło
for (int i in Collection<Integer>)
b / c NPE znajduje się w absolutnie nieoczekiwanym miejscu. Właściwie nie używam liczby Integer z autoboxingiem, ponieważ zakres pamięci podręcznej jest mały (choć można go zwiększyć w opcji / XX), ale mam klasę o nazwie IntegerProvider (od 1.1), która robi to samo. Korzystanie z mapy (dowolne z java.util) Integer-> Cokolwiek jest zwykle hitem wydajnościowym, chyba że jest używane w trywialnych przypadkach i prawie zawsze istnieje lepsze rozwiązanie.Przetwarza to jako
Integer <minus operator> 128
i nie znajduje zmiennejInteger
. Będziesz musiał zawinąć-128
w nawiasy:źródło
Problem polega na tym,
-
że kompilator widzi to jako operator.źródło
Linia 3 jest interpretowana tak, jakbyś próbował odjąć 128 od wyrażenia w nawiasie, a wyrażenie w nawiasie nie jest wyrażeniem typu int (traktuje „-” jako operator „-”). Jeśli zmienisz wyrażenie na:
wtedy kompilator zrozumie, że „-” jest jednoargumentowym minusem, który wskazuje ujemną liczbę całkowitą.
źródło
Kompilator C # ma to samo zachowanie. Daje lepszą wskazówkę, dlaczego się nie kompiluje:
źródło