2010-01-17 61 views

Trả lời

30

Như bây giờ bạn đã đề cập đúc ... có sự khác biệt trong trường hợp này:

byte a = 5; 
a += 10; // Valid 
a = a + 10; // Invalid, as the expression "a + 10" is of type int 

Từ Java Language Specification section 15.26.2:

Một biểu thức phân công hợp chất có dạng E1 op= E2 tương đương với E1 = (T)((E1) op (E2)), trong đó T là loại E1, ngoại trừ E1 chỉ được đánh giá một lần.

Điều thú vị, ví dụ họ đưa ra trong spec:

short x = 3; 
x += 4.6; 

là hợp lệ trong Java, nhưng không trong C# ... về cơ bản trong C# trình biên dịch thực hiện chuyên vỏ của + = và - = để đảm bảo rằng biểu thức là một trong hai loại mục tiêu hoặc là một chữ trong phạm vi của loại mục tiêu.

+0

Xin hãy tha thứ cho sự thiếu hiểu biết của tôi, nhưng tại sao 'a + 10' là kiểu int, khi đã được định nghĩa là byte? –

+0

@ Raúl: Do quảng bá số nhị phân. Có hiệu quả, không có toán tử 'byte + (byte, byte)'. Xem http://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.6.2 –

+0

Ồ, cảm ơn Jon. –

16

Không có sự khác biệt, một là viết tắt cho người khác. Ngay cả trình biên dịch sẽ tạo ra các hướng dẫn tương tự cho cả hai.

Chỉnh sửa: trình biên dịch KHÔNG tạo cùng mã cho cả hai, như tôi vừa phát hiện ra. Kiểm tra điều này:

dan$ cat Test.java 
public class Test { 
    public static void main(String[] args) { 
     int a = 0; 
     a = a + 10; 
     a += 20; 
    } 
} 

dan$ javap -c Test 
Compiled from "Test.java" 
public class Test extends java.lang.Object{ 
public Test(); 
    Code: 
    0: aload_0 
    1: invokespecial #1; //Method java/lang/Object."<init>":()V 
    4: return 

public static void main(java.lang.String[]); 
    Code: 
    0: iconst_0 
    1: istore_1 
    2: iload_1 
    3: bipush 10 
    5: iadd 
    6: istore_1 
    7: iinc 1, 20 
    10: return 

} 

Vì vậy, câu trả lời ngắn, đặc biệt cho người mới bắt đầu Java, hoặc bất kỳ ai không lo lắng về việc tối ưu hóa ở mức nhỏ nhất, là chúng có thể hoán đổi cho nhau. Câu trả lời dài sẽ phụ thuộc vào tôi đọc về iadd vs iinc.

Chỉnh sửa 2: Ok, tôi quay lại. Các thông số kỹ thuật hướng dẫn là (xấp xỉ) như sau:

iadd - cho biết thêm hai ints đầu trên stack

iinc - increments một biến địa phương bằng một hằng số

Và như chúng ta đã thấy ở trên , chúng tôi có thể lưu một vài hướng dẫn sử dụng iinc, miễn là có một hằng số ở phía bên tay phải.

Nhưng điều gì xảy ra nếu chúng tôi có

a += a?

Sau đó mã trông như thế này:

7: iload_1 
    8: iload_1 
    9: iadd 
    10: istore_1 

đó là điều tương tự ta nhận được nếu chúng ta có a = a + a.

+0

tôi biết điều này. nhưng tôi đọc có điều gì đó khác biệt liên quan đến việc truyền. tôi không hiểu nên hỏi ở đây để biết thêm về điều đó. – GuruKulki

+1

Bạn nên làm rõ điều đó trong phần chủ đề. – BalusC

+0

@danben: Rất vui khi thấy bản chỉnh sửa (vì trình biên dịch * không * tạo cùng một mã). Nhưng một khi một JVM được kích hoạt JIT (như HotSpot) được đặt trên bàn tay của nó, nghi ngờ của tôi là nếu không có hiệu ứng nào khác từ biểu thức, thậm chí dạng dài hơn sẽ được tối ưu hóa cho hoạt động gia tăng. –

4

Trong biểu thức mà bạn thấy, họ là tương đương, trong một biểu thức như:

array[getIndex(context)][some/complex + expression] += offset; 

bạn sẽ có được một ý tưởng trong đó các tình huống sự + = điều hành (và các nhà khai thác nhiệm vụ khác) là hữu ích. Nếu biểu thức là không tầm thường, toán tử + = ngăn ngừa lỗi và cải thiện khả năng đọc và do đó có thể bảo trì.

5

Điều này được xác định trong Java Language Specification, section 15.25.2. Phần nổi bật là:

Một biểu thức gán ghép của hình thức E1 op = E2 tương đương với E1 = (T) ((E1) op (E2)), trong đó T là loại E1, ngoại trừ E1 là chỉ được đánh giá một lần.

Đó là, trong trường hợp của bạn sự khác biệt là các loại ngầm dàn diễn viên:

byte a = 100; 
a += 1000; // compiles 
a = a + 1000; // doesn't compile, because an int cannot be assigned to a byte. 
+0

Và giá trị nào sẽ là 'byte a = 100; a + = 1000; 'gán cho a? –

+0

8 bit quan trọng nhất của biểu diễn nhị phân của 1100, giống như đúc một int đến một byte luôn luôn. – meriton

1

Có một số thuật ngữ trong S/lĩnh vực W, tôi có thể giải thích điều này với bạn,

trong a=a+1 chuyển nhượng cho a được đo sau hai bước

  1. Hệ thống tính giá trị của một (một bản sao riêng biệt mới được tạo ed đây)
  2. Hệ thống thêm 10 đến cô lập biến a thì giá trị của cô lập a được gán cho phía bên trái a

Nhưng trong trường hợp thứ hai,

  1. hệ thống biết giá trị của a và trực tiếp thêm 10 vào một (không có bản sao bị cô lập nào được thực hiện ở đây).

Hy vọng điều này sẽ rất hữu ích đối với bạn, và một điều nữa, chúng ta thường sử dụng phương pháp đó là a += 10; vì nó giảm chi phí hoạt động, theo người khác một,

Các vấn đề liên quan