2013-08-11 23 views
16

Mam 2 pytania z tym kodem segmentówKońcowy parametr w metodzie w java

  1. metoda 1 jest w porządku i metody pracy 2 nie. Jaki jest tego powód?
  2. W metodzie 1 wartość zwracana to bajt (8 bitów). Ale faktycznie zwracamy wartość char (16 bitów). co się tutaj dzieje?

// metoda 1

static byte m1() { 
    final char c = 'b'-'a'; 
    return c; 
} 

// metoda 2

static byte m3(final char c) { 
    return c; // 3 
} 
+3

Co masz na myśli, mówiąc, że nie działa? –

+1

podczas kompilacji mówi: error: możliwa utrata precyzji – chathura

+0

Być może statyczna optymalizacja w metodzie 1? –

Odpowiedz

23

char w Javie jest 16 bit unsigned wartość, natomiast byte jest 8 bitowa wartość. Dozwolony zakres dla bajtu to [-128, 127]. Tak więc, nie wszystkie postaci mogą być przypisane w byte.

W pierwszej metodzie, jesteś Zwracanie char z punkt kodowy = 1 ('b' - 'a'). Teraz, odkąd zdefiniowałeś char jako final, i przypisując do niego wyrażenie stałe, staje się stałą czasową kompilacji. Tak więc kompilator nie daje żadnego błędu kompilatora.

Od JLS Section 5.2:

If the expression is a constant expression (§15.28) of type byte, short, char, or int:
- A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable.

Podkreślenie moje.

Jeśli jednak zrobić c nieostatecznej, będzie to również spowodować błąd kompilatora:

static byte m1() { // This will be an error 
    char c = 'b'-'a'; 
    return c; 
} 

Powodem jest to, c nie jest czas kompilacji stały dłużej, a kompilator nie robi niejawny downcast.

W drugiej metodzie zwracasz char, którą zdałeś. Parametr c nie ma stałej czasowej kompilacji. Podczas kompilacji nie wiadomo, jaką wartość może uzyskać metoda. Podobnie, jeśli zdasz char z punktami kodowymi spoza zakresu dozwolonej wartości byte, to nie będzie działać.

Aby 2nd pracę metodzie można robić wyraźne Obsada:

static byte m3(final char c) { 
    return (byte)c; // 3 
} 
+0

@ Baabai. Nie. Nigdy nie pracowałem nad Ruby. Jestem osobą z Java. –

+0

Ohh! w jakiej jesteś firmie? –

+0

@ Baabai. Infosys. –

1

W metodzie 2, kompilator nie może sprawić, zwężający się niejawny oddanych od rozmowy do bajta, ponieważ może to spowodować utratę precyzja (Java obsługuje znaki Unicode, a typ pierwotny znaku jest zdefiniowany z rozmiarem 16 bitów informacji, inaczej niż język C, w którym zwykle jest 8 bitów)

W przypadku metody 1 kompilator może jednak ustalić, że stała wartość "b" - "a" nie spowoduje w rzeczywistości utraty dokładności, a zatem pozwala na wykonanie niejawnego rzutowania.

Spójrz na: http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html

2

W m1() kompilator widzi, że char c jest stała o wartości 1 i dlatego nie narzekać, gdyż wie, że może on być stworzony do bajta. Jeśli zmienisz go na final char c = 128, gdzie 127 to maksymalny rozmiar byte, otrzymasz skargę, podobnie jak wtedy, gdy usuniesz zmienny deskryptor zmiennej final z .

+0

Czy możesz wyjaśnić, dlaczego wystąpił błąd po usunięciu ostatniego słowa kluczowego? – chathura

+0

Po usunięciu 'final' nie jest już stałą. Zatem kompilator nie może mieć pewności, że nie zmieni się w przyszłości (mimo że metoda kończy się w następnym wierszu, kompilator nie jest tego świadomy). Kiedy jest "ostateczny znak c" z przypisaną wartością, kompilator po prostu widzi go jako numer 127, który nie ma problemu, aby zostać bezpiecznie przekształcony w dowolny typ liczby całkowitej. Pamiętaj, że 'char' w języku Java ma zakres od 0 do 65 535, ponieważ ma 16 bitów. http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html –

0

Teraz powodemdziała i m3() nie jest, ponieważ w m1() c jest compile-time constant.

Analizować ten kod:

byte b = 'x'; //compile-time constant 
    int i = 'x'; //compile-time constant 
    char c = 'x'; //compile-time constant 
    c = i; //compilation error 
    c = b; //compilation error 
    b = i; //compilation error 
    b = c; //compilation error 
    i = b; // Okay 
    i = c; // Okay 

Compiler nie zrobi niejawny obsady, która może ewentualnie spowodować utratę danych, dla zmiennych run-time.

Powiązane problemy