2017-04-13 20 views
7
short s = 'a';  // valid 
Short ss = 'a';  // valid 
int i = 'a';   // valid 
Integer ii = 'a'; // invalid 

Tại sao số nguyên ii = 'a' không hợp lệ, nhưng int i = 'a' hợp lệ? Tại sao Short ss = 'a' hợp lệ, nhưng Integer ii = 'a' không hợp lệ?quy tắc chuyển nhượng kỳ lạ java


một bộ câu hỏi:

byte b; 
final short s = 1; 
final Short ss = 1; 
final int i =1; 
final Integer ii = i; 
final long L = 1; 
final Long LL =1L; 

b = s;  // valid 
b = ss; // invalid 
b = i;  // valid 
b = ii; // invalid 
b = L;  // invalid 
b = LL; // invalid 

Tại sao b = L; không hợp lệ, trong khi b = s; có hiệu lực ?

Xin vui lòng, đừng nói đó là tất cả vì JLS đã nói như vậy. Tôi muốn biết tại sao JLS có những quy tắc không phù hợp và không trực quan này. Tôi đã bỏ lỡ cái gì?

+6

Vì autoboxing (và mở rộng chuyển đổi nguyên thủy) không hoạt động để tạo một 'char' thành' Integer'. Hãy thử 'Integer ii = (int) 'a'; ' –

+0

ii là thể hiện của lớp trong khi i là thể hiện của kiểu dữ liệu nguyên. – Omore

+1

Thời gian thích hợp để tìm hiểu về 'Tự động và Bỏ hộp' trong java. https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html – yogidilip

Trả lời

5

Vì vậy, dòng:

Short s = 'a'; // is valid ... 

char là unsigned giá trị 16-bit (giá trị tối đa là 65.536) và ngắn được ký giá trị 16-bit (giá trị tối đa là 32.767), do đó, có một chuyển đổi thô sơ thu hẹp (char để ngắn) tiếp theo là một chuyển đổi quyền anh (ngắn thành ngắn).

short s = 'a'; // is valid - this is a narrowing primitive conversion (char -> short) 

Đây là những special cases:

Bên cạnh đó, nếu biểu thức là một biểu thức hằng của loại byte, ngắn, char, hoặc int:

  • Một mồi thu hẹp chính kịp thời chuyển đổi có thể được sử dụng nếu loại biến là byte, ngắn, hoặc char, và giá trị của biểu thức hằng thể được biểu diễn trong các loại của biến.

Chuyển đổi nguyên thủy thu hẹp theo sau là một chuyển đổi quyền anh có thể được sử dụng nếu kiểu của biến là:

  • Byte và giá trị của biểu thức liên tục được biểu diễn trong các loại byte.

  • ngắn và giá trị của biểu thức liên tục được biểu diễn trong loại ngắn.

  • Character và giá trị của biểu thức liên tục được biểu diễn trong loại char.

Hãy đi đến các ví dụ tiếp theo:

Integer ii = 'a'; // is invalid - not a special case according to Oracle docs 
int i = 'a';  // is valid - widening primitive conversion (char -> int) is allowed 

Và một trong nhiều trường hợp từ câu hỏi của bạn:

byte b; 
final long L = 1; 
b = L // error - incompatible types 

Tại sao dòng b = L là không hợp lệ? Bởi vì nó không phải là một trường hợp đặc biệt được mô tả ở trên và chúng ta có thể mất thông tin trong một dàn diễn viên, đó là lý do tại sao bạn phải thực hiện nó một cách rõ ràng:

b = (byte) L; // is valid - narrowing primitive conversion (long -> byte) 

Ngoài ra, có một cái nhìn vào một rất hữu ích table.

Có rất nhiều thông tin về tất cả các quy tắc này trong tài liệu JLS và bạn không cần phải lo lắng về tất cả chúng. Những gì tôi có thể nói về câu hỏi cuối cùng của bạn là không có chuyển đổi hẹp ngầm bất kỳ số nguyên theo nghĩa đen sẽ đòi hỏi một dàn diễn viên trong các trường hợp sau:

// Cast is permitted, but not required - profit! 
byte b = (byte) 100; 
short s = (short) 100; 

Nhờ đó chúng ta có thể thay đổi nó thành:

byte b = 100; 
short s = 100; 
+0

Cảm ơn bạn đã trả lời chi tiết. Tôi hiểu lời giải thích của bạn. Đó là tất cả vì JLS đã nói như vậy. Nhưng tại sao JLS lại có những quy tắc kỳ lạ này? Các quy tắc không nhất quán. Ví dụ; Một nguyên thủy thu hẹp chỉ xảy ra nếu biểu thức là một biểu thức liên tục của kiểu byte, ngắn, char hoặc int. Nhưng không lâu? những gì là sai với dài? –

+0

@VincentQuan một chuyển đổi thu hẹp nguyên thủy không bao giờ có ý nghĩa đối với 'long', bởi vì nó là kiểu số nguyên nguyên lớn nhất. – Hulk