2015-05-20 15 views
24

I zostały badania casting char i pojechałem przez to:Java char bajt do odlewania

public class Test { 
    public static void main(String a[]) { 
     final byte b1 = 1; 
     byte b2 = 1; 
     char c = 2; 

     c = b1; // 1- Working fine 
     c = b2; // 2 -Compilation error 
    } 
} 

Może ktoś wyjaśnić, dlaczego to działa dobrze w 1, gdy dodałem ostateczna do bajt?

+0

Generalnie rzutowanie z bajtów na znaki i na odwrót nie jest dobrą praktyką, ponieważ ignoruje kodowanie. – Necreaux

Odpowiedz

18

Gdy zmienna jest final, kompilator automatycznie inlines jej wartość, która wynosi 1. Wartość ta jest przedstawianego jako char, tj:

c = b1; 

jest równoważna

c = 1; 

W rzeczywistości, zgodnie z this section on final variables, , , b1 jest traktowany jako stała:

Zmienna typu pierwotnego lub typu String, czyli final i zainicjowana za pomocą wyrażenia stałego w czasie kompilacji (§ 15.28), jest nazywana zmienną stałą .

+2

nadal nie powinno być żadnej różnicy. – loonytune

+3

@loonytune Tak, kompilator to robi. Zweryfikowano przy użyciu 'javac 1.7.0_75'. – manouti

+1

Masz rację, zweryfikowano także na java 8. Jestem naprawdę zaskoczony, prawdopodobnie chodzi o to, że jest stałym wprowadzeniem do tabeli symboli podczas kompilacji i wcale nie jest zmienną. Przepraszam za to, wznowiłem twój komentarz i odpowiedź ... – loonytune

0

Cóż, jego ponieważ bajt jest podpisana typ podczas char nie jest, więc u trzeba zastosować wyraźny konwersji typu dla (2)

c = (char)b2; 

również końcowa deklaracja pracował dla 1, ponieważ przed kompilacją , kompilator jest w stanie potwierdzić, że nie ma żadnej straty z powodu konwersji, ponieważ '1' jest w zakresie znaków, spróbuj umieścić '-1' z tym samym końcowym stwierdzeniem w (1) ponownie dostaniesz błąd kompilacji.

Wszystko to sprowadza się do zgodności typów między typami podpisanymi i niepodpisanymi ... co należy zrobić jawnie w java.

10

Konwersja z byte na char jest rozszerzającą i zwężającą się konwersją pierwotną, zgodnie z opisem w paragraph 5.1.4 specyfikacji języka Java.

Jak opisuje to JLS, odbywa się to poprzez etap pośredni; byte jest konwertowany na int poprzez rozszerzającą się prymitywną konwersję, a następnie int jest konwertowany na char poprzez zwężającą się prymitywną konwersję (patrz 5.1.3).

Paragraph 5.2 wyjaśnia gdy obsada jest konieczna, kiedy wykonujesz zadanie:

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

  • Można zastosować zwężającą się konwersję pierwotną, jeśli typ zmiennej to byte, short, lub char, a wartość wyrażenia stałego jest reprezentowalna w typie zmiennej.

zmiennej b1 rzeczywiście jest stała, ale zmienna b2 nie jest, więc ta reguła dotyczy b1 ale nie dla b2.

Więc: można przypisać do cb1b1 ponieważ jest stała i wartość stałą, 1, mieści się w char, ale nie można przypisać b2 do c bez obsady, ponieważ b2 nie jest stała.

+0

Tak ... dużo ... złożoność ... –

+0

@PaulDraper Cóż, są to tylko oficjalne reguły ze specyfikacji językowej, które wyjaśniają dokładnie, dlaczego jeden działa, a drugi to błąd. Ostatecznie wszystko, co musisz pamiętać, to to, że nie musisz rzucać, jeśli jest stała. Powód, dla którego nie musisz w tym przypadku rzucać, dotyczy wygody. – Jesper