2015-05-21 14 views
12

W mojej klasie castingu nauczyciel nauczył nas interesującego faktu w następujący sposób.Ostateczna koncepcja odlewania nie dotyczy przeciążenia

class Casting { 
    public static void main(String args[]){ 
     int i = 10; 
     byte b = i; 
     System.out.println(b); 
    } 
} 

Mamy błąd

java:5: possible loss of precision 

A potem zmienił kod w następujący sposób

class Casting1 { 
    public static void main(String args[]){ 
     final int i = 10; 
     byte b = i; 
     System.out.println(10); 
    } 
} 

10 

Mamy poprawny wynik. Z tego powodu powiedział, że gdy zmienimy zmienną, zmienna jest przechowywana w najmniejszym możliwym typie danych. W tym przypadku był to byte. Z tego powodu mogliśmy go przesyłać bez użycia słowa kluczowego "cast".

Ale kiedy używamy metody przeciążeniu takiego,

class A { 
    void m(int i){ 
     System.out.println("int"); 
    } 
    void m(byte b){ 
     System.out.println("byte"); 
    } 
    public static void main(String args[]){ 
     A a1 = new A(); 
     final int i = 10; 
     a1.m(i); 
    } 
} 

uzyskać wyjście int. Jeśli ostateczne zmienne są przechowywane w najniższym możliwym typie danych, powinno to być byte. Więc próbowałem poniższy kod bez przeciążania.

class A { 
    void m(byte b){ 
     System.out.println("byte"); 
    } 
    public static void main(String args[]){ 
     A a1 = new A(); 
     final int i = 10; 
     a1.m(i); 
    } 
} 

java:9: m(byte) in A cannot be applied to (int) 

Jaki jest tego powód? Czy jest jakiś punkt, który źle zrozumiałem?

+1

w przykładzie z końcem, przekazujesz stałą 10 do println prawdopodobnie powinno b. powinieneś sprawdzić czy ta literówka istnieje w twoim kodzie, może to zmieni wynik? –

+0

pierwszy przykład daje mi błąd kompilacji: niezgodność typu: nie można konwertować z int na bajt, drugi przykład (z końcem) przechodzi kompilację –

+0

@sharonbn Tak, tak powinno być. Wspomniałem, że dostaję błąd –

Odpowiedz

2

Miksujesz przestrzeń pamięci zmiennych i ich typy. Wywołanie metody m (...) spowoduje przede wszystkim sprawdzenie typu zmiennej parametrycznej. Tutaj jest to int, więc wybierze odpowiednią przeciążoną metodę, bez względu na wielkość int w pamięci.

Chociaż naprawdę doceniam pierwszy przykład, który wprowadza światło w jedną z cech ostatecznego identyfikatora.

0

Is there any point that I have misunderstood?

Tak. Poszukiwanie, która metoda zostanie zastosowana, zależy od typów argumentów. W przeciwieństwie do przypisania, nie ma żadnej próby konwersji argumentów metody (przynajmniej nie było, zanim dodano do niej autoboxing, który dodaje inny zestaw arbitralnych reguł).

0

Jeśli konwersja jest częścią przypisania, a wartość może być dopasowana do byte, kompilator automatycznie wykona konwersję.

W dokumencie JLS wyjaśniono wyraźnie, że jest to przypadek specjalny, który ma zastosowanie tylko do przypisania , a nie do konwersji w innych kontekstach.

Warto wspomnieć, że byte jest przydatny tylko podczas programowania urządzeń wbudowanych lub obsługi plików/sieci. byte i int zajmują to samo miejsce, ponieważ adresy zmiennych są wyrównane.

2

Ten bit nie jest całkiem poprawne ...

„Jak z tego powodu, powiedział, że kiedy zmodyfikować zmienną końcowego zmienną jest przechowywany w najmniejszym możliwym typem danych. W tym przypadku była bajt."

Nie zapisuje go jako bajtu, przechowuje go jako int, ALE jest faktycznie stałą, więc gdy Java kompiluje linię byte b = i;, to na pewno wie, że wartość będzie 10, która nie robi". t potrzebujesz odlewania

+0

Dziękuję za uwagę popraw –

+0

@Phil, W swojej odpowiedzi wspomniałeś, że "Ostateczne zmienne nie wymagają rzucania". czy możesz wyjaśnić to stwierdzenie? –

+1

@Anil: Pewnie! Nie chodzi o to, że ostateczne zmienne nie wymagają odlewania jako takiego. Po prostu kompilator Java może skutecznie traktować je jak stałe, ponieważ wie, że nigdy się nie zmienią. SO ... bajt b = i jest taki sam jak bajt b = 10, który nie wymaga rzucania. Czy to pomoże ci to wyjaśnić? –