@starblue, czy istnieje przykład z życia wzięty, w którym można zastosować typ bajtu Java?
Thorbjørn Ravn Andersen
Jeśli istnieją dane, które są określone jako bajt, użyj języka Java bytedla przejrzystości, np. W parametrach. W takim przypadku fakt, że nie możesz przypisać intwartości, może nawet wyłapać pewne błędy. Lub użyj, byteaby zaoszczędzić miejsce w tablicach. Nie użyłbym bytedla pojedynczej wartości, która po prostu mieści się w bajcie.
starblue
Odpowiedzi:
172
Stałe są oceniane jako ints, więc 2147483647 + 1przepełniają i dają nowy int, który można przypisać do int, a 127 + 1jednocześnie jest oceniany jako intrówny 128i nie można go przypisać byte.
Problem jest intzwiązany z binarną promocją liczbową, wartością 127jest czerwony śledź.
starblue
Wolałbym, aby stałe były oceniane z nieskończoną precyzją, dając również błąd int i = 2147483647 + 1;
Eduardo
@MByD: Jak powiedziałeś " while 127 + 1 also evaluated as int equals to 128, and it is not assignable to byte.", czy to oznacza, że 50 + 1 zostanie ocenione jako bytei dlatego można je przypisać do byte?
Bhushan
1
@ 10101010 - niezupełnie. będzie można go przypisać do bajtu, ale najpierw (zgodnie ze standardem) zostanie oszacowany jako int.
MByD
35
Literał 127 oznacza wartość typu int. Podobnie robi dosłowne 1. Suma tych dwóch jest liczbą całkowitą 128. Problem w drugim przypadku polega na tym, że przypisujesz to zmiennej typu bajt. Nie ma to nic wspólnego z rzeczywistą wartością wyrażeń. Ma to związek z tym, że Java nie obsługuje wymuszeń (*). Musisz dodać typecast
byte b =(byte)(127+1);
a potem się kompiluje.
(*) przynajmniej nie takiego rodzaju, jak łańcuch do liczby całkowitej, zmiennoprzecinkowy do czasu, ... Java obsługuje wymuszanie, jeśli w pewnym sensie nie powoduje utraty (Java nazywa to „poszerzaniem”).
I nie, słowo „przymus” nie wymagało poprawiania. Zostało to wybrane bardzo celowo i właściwie. Z najbliższego źródła (Wikipedia): „W większości języków słowo wymuszenie jest używane do określenia niejawnej konwersji podczas kompilacji lub w czasie wykonywania”. oraz „W informatyce konwersja typów, rzutowanie typów i wymuszanie są różnymi sposobami pośredniej lub jawnej zmiany jednostki jednego typu danych na inny”.
Twój przykładowy kod powinien prawdopodobnie mieć postać bajt b = (bajt) 127 + 1; czyli „Dodaj 1 do maksymalnej wartości bajtu”, Twój przykład po prostu zamienia wartość int równą 128 na wartość bajtową.
NKCSS
6
@NKCSS - nie sądzę, że masz rację, to - (byte)(127 + 1)rzut 128 (integer) na bajt, podczas gdy to (byte)127 + 1rzutuje 127 na bajt, ale potem znowu na int, ponieważ jest dodawany do 1 (int) i ty get 128 (int), a błąd pozostaje.
MByD
6
Jako dowód dla @MByD:
Następujący kod jest kompilowany:
byte c =(byte)(127+1);
Ponieważ chociaż wyrażenie (127 + 1)jest int i poza zakresem poza bytetypem, wynik jest rzutowany na byte. To wyrażenie tworzy -128.
Ponadto, jeśli wyrażenie jest wyrażeniem stałym (§15.28) typu byte, short, char lub int:
Zwężającą konwersję pierwotną można zastosować, jeśli typ zmiennej to bajt, krótka lub znak, a wartość wyrażenia stałego można przedstawić w typie zmiennej.
Bez tej klauzuli nie moglibyśmy pisać
byte x =0;char c =0;
Ale czy powinniśmy być w stanie to zrobić? Nie sądzę. Wśród prymitywów zachodzi pewna magia, trzeba być bardzo ostrożnym. Zrobiłbym wszystko, żeby pisać
jeśli chodzi o pytanie, czy powinniśmy być w stanie ... nie widzę w tym nic złego, byte x = 0ale z drugiej strony jestem programistą C.
Grady Player
Być może mógłbym zobaczyć argument przeciwko char c = 0, ale dlaczego bajt x = 0 jest zły?
Michael Burge
To mylące dla niewprawnych oczu, myśląc, że przypisują bajt 0 do zmiennej bajtowej. W tym przykładzie niewiele szkodzi, ale ogólnie operowanie na bajt / krótki / znak może być bardzo mylące z powodu niejawnych konwersji. Są o wiele bardziej skomplikowane, niż mogłoby się wydawać. Chcę, aby mój kod był jak najbardziej przejrzysty, nie wprowadzaj żadnej niepewności ze względu na oszczędność kilku naciśnięć klawiszy.
niezaprzeczalny
Czy podobna zasada ma zastosowanie, gdy zawężająca konwersja pierwotna jest z long na int, np. Int i = 1 + 0L? Po prostu pytam, ponieważ cytowany tekst wyraźnie pomija ten przypadek.
byte
typ danych jest taki bolesny ?!byte
jest podpisany zamiast niepodpisanego.byte
dla przejrzystości, np. W parametrach. W takim przypadku fakt, że nie możesz przypisaćint
wartości, może nawet wyłapać pewne błędy. Lub użyj,byte
aby zaoszczędzić miejsce w tablicach. Nie użyłbymbyte
dla pojedynczej wartości, która po prostu mieści się w bajcie.Odpowiedzi:
Stałe są oceniane jako ints, więc
2147483647 + 1
przepełniają i dają nowy int, który można przypisać doint
, a127 + 1
jednocześnie jest oceniany jakoint
równy128
i nie można go przypisaćbyte
.źródło
int
związany z binarną promocją liczbową, wartością127
jest czerwony śledź.while 127 + 1 also evaluated as int equals to 128, and it is not assignable to byte.
", czy to oznacza, że 50 + 1 zostanie ocenione jakobyte
i dlatego można je przypisać dobyte
?Literał 127 oznacza wartość typu int. Podobnie robi dosłowne 1. Suma tych dwóch jest liczbą całkowitą 128. Problem w drugim przypadku polega na tym, że przypisujesz to zmiennej typu bajt. Nie ma to nic wspólnego z rzeczywistą wartością wyrażeń. Ma to związek z tym, że Java nie obsługuje wymuszeń (*). Musisz dodać typecast
a potem się kompiluje.
(*) przynajmniej nie takiego rodzaju, jak łańcuch do liczby całkowitej, zmiennoprzecinkowy do czasu, ... Java obsługuje wymuszanie, jeśli w pewnym sensie nie powoduje utraty (Java nazywa to „poszerzaniem”).
I nie, słowo „przymus” nie wymagało poprawiania. Zostało to wybrane bardzo celowo i właściwie. Z najbliższego źródła (Wikipedia): „W większości języków słowo wymuszenie jest używane do określenia niejawnej konwersji podczas kompilacji lub w czasie wykonywania”. oraz „W informatyce konwersja typów, rzutowanie typów i wymuszanie są różnymi sposobami pośredniej lub jawnej zmiany jednostki jednego typu danych na inny”.
źródło
(byte)(127 + 1)
rzut 128 (integer) na bajt, podczas gdy to(byte)127 + 1
rzutuje 127 na bajt, ale potem znowu na int, ponieważ jest dodawany do 1 (int) i ty get 128 (int), a błąd pozostaje.Jako dowód dla @MByD:
Następujący kod jest kompilowany:
Ponieważ chociaż wyrażenie
(127 + 1)
jest int i poza zakresem pozabyte
typem, wynik jest rzutowany nabyte
. To wyrażenie tworzy-128
.źródło
JLS3 # 5.2 Konwersja przypisania
(zmienna = wyrażenie)
Ponadto, jeśli wyrażenie jest wyrażeniem stałym (§15.28) typu byte, short, char lub int:
Zwężającą konwersję pierwotną można zastosować, jeśli typ zmiennej to bajt, krótka lub znak, a wartość wyrażenia stałego można przedstawić w typie zmiennej.
Bez tej klauzuli nie moglibyśmy pisać
Ale czy powinniśmy być w stanie to zrobić? Nie sądzę. Wśród prymitywów zachodzi pewna magia, trzeba być bardzo ostrożnym. Zrobiłbym wszystko, żeby pisać
źródło
byte x = 0
ale z drugiej strony jestem programistą C.int i=0L
jest nielegalne.