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 3
int
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ư a
và b
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 a
và b
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
?
Vì 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 a
và b
constants
:
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
) .
'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
@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
@dosdebug Không, không có thêm ở đây. Nó được biên dịch giống như 'short c = 3; ' – Neo