2013-08-28 12 views
5
byte a = 1; 
byte b = 1; 
byte c = a + b; 

Zgłasza błędzie: możliwość utraty precyzjiCzy dodatek bajtów konwertuje na int z powodu reguł języka Java lub z powodu jvm?

byte subt = a_s - a_b; 
       ^
    required: byte 
    found: int 

Czy takie zachowanie ma coś wspólnego z JVM lub jego zostały zdefiniowane w języku Java.

EDYCJA: A jeśli jest zdefiniowany w języku Java, to robi to z powodu utrzymania jvm na uwadze?

Środki jeśli java obsługuje byte typ danych to dlaczego operation on byte powoduje int

+0

bajt C = A + B; Wyniki są błędne ... b + = a; Kompiluje się pomyślnie. Czemu ? –

Odpowiedz

11

if java supports byte datatype then why operation on byte results int

Bo to jak wirtualna maszyna Java jest zaprojektowany. Nie ma instrukcji ustawionej do wykonywania operacji na typie bajtowym. Zamiast tego zestaw instrukcji dla typu int jest używany do operacji na typach boolean, byte, char i short.

Od JVM Spec - Section 2.11.1:

A compiler encodes loads of literal values of types byte and short using Java Virtual Machine instructions that sign-extend those values to values of type int at compile-time or run-time. Loads of literal values of types boolean and char are encoded using instructions that zero-extend the literal to a value of type int at compile-time or run-time. [..]. Thus, most operations on values of actual types boolean , byte , char , and short are correctly performed by instructions operating on values of computational type int .

Powodem tego jest również określony w tym odcinku:

Given the Java Virtual Machine's one-byte opcode size, encoding types into opcodes places pressure on the design of its instruction set. If each typed instruction supported all of the Java Virtual Machine's run-time data types, there would be more instructions than could be represented in a byte . [...] Separate instructions can be used to convert between unsupported and supported data types as necessary.

o szczegóły na jakie są dostępne dla różnych typów wszystkie zestawy instrukcji, można przejść przez tabela w tej sekcji.

Istnieje również tabela określająca odwzorowanie rzeczywistego typu do JVM typu obliczeniowej:

+0

+1 Gdy JIT optymalizuje kod do natywnego kodu, może używać dowolnego typu, który lubi. To nie musi być typ "int". –

+1

Czy Java nadal nie będzie w stanie przekonwertować ich na 'int', wykonać operacji i przekonwertować z powrotem na' byte'? Specyfikacja JLS wydaje się bardziej odpowiednia, chociaż może to wyjaśniać uzasadnienie tej części JLS. – Dukeling

+0

@PeterLawrey Czy ten kod źródłowy będzie powiązany z Javą? To może być inny język. Czy mam rację? Bardzo mały pomysł na optymalizację JIT. –

0

Tak, to język spec.

Dodatkowy operator (+). podczas gdy dodanie, 'a' jest konwertowane (niejawnie rzuca) na typ int, b, a także na typ int. Stąd result jest domyślnie typu int.

To samo dotyczy również operatora .

+0

To jest specyfikacja językowa, ale czy jesteś pewny, że cytujesz odpowiednią sekcję? – Thilo

+0

@Thilo Tak. Masz rację. Dukelinkg jest poprawnie podłączony :) –

5

JLS 5.6.2: Binary Numeric Promotion obejmuje go:

Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:

  • If either operand is of type double , the other is converted to double .

  • Otherwise, if either operand is of type float , the other is converted to float .

  • Otherwise, if either operand is of type long , the other is converted to long .

  • Otherwise, both operands are converted to type int .

10

Kompilator robi słusznie. Ponieważ (a + b) może przekroczyć maksymalną wartość, która może być przechowywana w zmiennej bajtowej. Jeśli powiesz kompilatorowi a, wartości b nie zmienią się, używając słowa kluczowego "finał", nie będą już narzekać.

final byte a = 1; 
final byte b = 1; 
byte c = a + b; 
+0

to jest naprawdę naprawdę interesujące! bardzo dziękuję –

+0

Dziękuję za uproszczoną odpowiedź. –

+0

bajt c = a + b; Wyniki są błędne ... b + = a; Kompiluje się pomyślnie. Czemu ? –

0

Podczas wykonywania operacji arytmetycznych na żadnych argumentów wynik jest przechowywane w tej formie MAX (int, operand1, typ operand2 ... typ operandN) Ex: byte a=10; byte b=20; byte c=a+b;

następnie wynik a + b będzie przechowywany w postaci MAX (int, operand1 type, operand2 type, ...typ operandN) w tym przypadku MAX (int, bajt, bajt) maksymalna wartość to int, która jest maksymalna, więc c będzie miało wartość int, ale c zostało zadeklarowane jako bajt, a my nie możemy przechowywać wartości int (większej) do bajtu (mniejszy). to samo dotyczy każdego operatora arytmetycznego.

dlatego błąd mówi błąd: Niezgodne typy: możliwe stratnej konwersji z int bajt

Powiązane problemy