2017-10-21 22 views
10

Tôi không thể nắm bắt ý tưởng của toán tử bổ sung hoặc short loại dữ liệu.Nhà điều hành Java +

Người ta nói rằng;

short a = 1; 
short b = 2; 
short c = a + b; 

mà sẽ không biên dịch vì điều hành bổ sung luôn đúc short, chart, byte dữ liệu các loại để int và tôi hiểu điều này. Nhưng điều này;

short c = 1 + 2; 

hoạt động hoàn toàn ổn. Vì vậy, nếu nhà điều hành bổ sung tự động chuyển đổi short thành int và sau đó áp dụng kết quả (trong đó kết quả ofcourse sẽ là một int), tại sao điều này hoạt động tốt?

Chỉnh sửa: Câu hỏi này không trùng lặp với Primitive type 'short' - casting in Java vì tôi hiểu quy trình chuyển đổi. Ngoài ra, câu hỏi nói về các chuyển đổi của các loại dữ liệu khi câu hỏi của tôi liên quan đến int literals.

+9

'1 + 2' có thể được tính tại thời gian biên dịch vì cả hai toán hạng đều là hằng số thời gian biên dịch. Nói cách khác 'short c = 1 + 2;' sẽ được biên dịch thành 'short c = 3;'. Bạn sẽ vẫn gặp lỗi nếu kết quả sẽ nằm ngoài phạm vi 'short'. – Pshemo

+0

@Pshemo Vì vậy, có nghĩa là, một 'int' sẽ được downcasted explicity để' short'? Bởi vì 1 + 2 được giải quyết là 'short' sẽ vẫn được đánh giá thành' int', không? – dosdebug

+5

@dosdebug Không, không có thêm ở đây. Nó được biên dịch giống như 'short c = 3; ' – Neo

Trả lời

0

Theo như tôi hiểu, Java hỗ trợ + cho int và dài, nhưng theo quy định, không cho ngắn. Không có chuyển đổi kiểu tự động, vì thao tác được xác định để được thực hiện trên các kiểu dữ liệu int hoặc dài.

Xem https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2

Nếu bạn muốn có được một kết quả hợp lệ, và biết rằng kết quả không gây ra một tràn, bạn có thể đúc kết quả:

short a = 1; 
short b = 2; 
short c = (short)(a + b); 
6

1 + 2 là một biểu thức hằng trong khi a + b thì không.
Điều quan trọng đối với việc đánh giá chúng.
Việc đầu tiên sẽ được thực hiện tại thời gian biên dịch, lần thứ hai khi chạy.

Các JLS 8 trạng thái:

15,28. Expressions liên tục

Một biểu thức hằng số là một biểu thức biểu thị một giá trị nguyên thủy loại hoặc một String mà không hoàn thành đột ngột và bao gồm sử dụng chỉ sau:

  • Literals kiểu nguyên thủy và literals kiểu string (§3.10.1, §3.10.2, §3.10.3, §3.10.4, §3.10.5)

  • phôi để loại nguyên thủy và phôi gõ string (§15.16)

  • Toán tử đơn nhất +, -, ~, và! (Nhưng không ++ hoặc -) (§15.15.3, §15.15.4, §15.15.5, §15.15.6)

  • Các nhà khai thác chất nhân *, /, và% (§15.17)

  • Toán tử cộng + và - (§15.18)

........................

đây:

short c = 1 + 2; 

1 + 2 là bao gồm hai số int chữ và một toán tử cộng.
Vì vậy, nó được coi là một biểu thức liên tục.
Biểu thức không đổi được đánh giá tại thời gian biên dịch.
Vì vậy short c được đánh giá là 3

Dưới đây là một lớp học mẫu:

package stackoverflow; 

public class EvaluationClass { 

    public void foo(){ 
     short c = 1 + 2; 
    } 
} 

Đây là mã tháo rời:

Compiled from "EvaluationClass.java" 
public class stackoverflow.EvaluationClass { 
    public stackoverflow.EvaluationClass(); 
    Code: 
     0: aload_0 
     1: invokespecial #1     // Method java/lang/Object."<init>":() 
     4: return 

    public void foo(); 
    Code: 
     0: iconst_3 
     1: istore_1 
     2: return 
} 

Chúng ta có thể thấy các hướng dẫn 0: iconst_3 rằng tải 3int lên ngăn xếp.


Trong khi ở đây:

short a = 1; 
short b = 2; 
short c = a + b; 

a + b được đánh giá chỉ trong thời gian chạy như ab không giá trị không đổi.
Giá trị của chúng thực sự có thể thay đổi bất kỳ lúc nào.
Lưu ý rằng trình biên dịch không cố gắng thông minh bằng cách đọc từng câu lệnh để đoán xem ab có đột biến hiệu quả hay không.
Nó cho rằng nó có thể và do đó đánh giá a + b chỉ khi chạy.

Trong trường hợp này, tại sao a + b không tạo ra short nhưng là int?
JLS 8 quy định rằng:

4.2.2. Integer Operations

Nếu một nhà điều hành số nguyên khác hơn là một nhà điều hành sự thay đổi có ít nhất một toán hạng kiểu dài, sau đó hoạt động được thực hiện bằng cách sử dụng chính xác 64-bit , và kết quả của các nhà điều hành số là loại dài . Nếu toán hạng khác không dài, nó được mở rộng đầu tiên (§5.1.5) để nhập dài bằng cách xúc tiến số (§5.6).

Nếu không, thao tác được thực hiện bằng độ chính xác 32 bit và kết quả của toán tử số là loại int. Nếu một trong hai toán hạng không phải là một int, nó được mở rộng đầu tiên để nhập int bằng cách xúc tiến số.


Là một mặt lưu ý, nếu thay đổi mã của bạn để làm cho abconstants:

final short a = 1; 
final short b = 2; 
short c = a + b; 

này sẽ biên dịch tốt tại như a + b sẽ được đánh giá là một biểu thức hằng số (3) .

+0

Cảm ơn bạn. Điều này đã được trả lời trong các bình luận của câu hỏi. Cảm ơn bạn đã viết thêm. – dosdebug