2011-10-06 27 views
5
byte b1 = 3; 
byte b2 = 0; 

b2 = (byte) (b2 + b1); // line 3 
System.out.println(b2); 

b2 = 0; 
b2 += b1;    // line 6 
System.out.println(b2); 

Lỗi trình biên dịch nếu chúng tôi không tạo kết quả cho byte - có thể do kết quả bổ sung luôn là int và int không khớp với một byte. Nhưng dường như chúng ta không phải đánh máy trên dòng 6. Không phải cả hai câu lệnh, dòng 3 và dòng 6, tương đương? Nếu không thì những gì khác là khác nhau?hành vi trình biên dịch khác nhau khi thêm byte

Trả lời

10

Có, hai dòng là tương đương - nhưng chúng sử dụng các phần khác nhau của ngôn ngữ và chúng được bao phủ bởi các phần khác nhau của JLS. Dòng 3 là toán tử + bình thường, được áp dụng cho các byte đã được thăng cấp thành int, cho kết quả là int. Điều đó phải được truyền trước khi bạn có thể gán lại cho biến số byte.

dòng 6 là một toán tử gán phức hợp như mô tả trong section 15.26.2 of the JLS:

Vào lúc chạy, khái niệm được đánh giá theo một trong hai cách. Nếu biểu thức toán hạng bên trái không phải là biểu thức truy cập mảng, thì cần có bốn bước:

  • Đầu tiên, toán hạng bên trái được đánh giá để tạo biến. Nếu việc đánh giá này hoàn thành đột ngột, thì biểu thức gán sẽ hoàn thành đột ngột vì cùng một lý do; toán hạng bên phải không được đánh giá và không có phép gán nào xảy ra.
  • Nếu không, giá trị của toán hạng bên trái được lưu và sau đó toán hạng bên phải được đánh giá. Nếu đánh giá này hoàn thành đột ngột, sau đó biểu thức gán hoàn thành đột ngột vì cùng một lý do và không có phép gán nào xảy ra.
  • Nếu không, giá trị đã lưu của biến bên tay trái và giá trị của toán hạng bên phải được sử dụng để thực hiện thao tác nhị phân được chỉ định bởi toán tử gán hợp chất. Nếu hoạt động này hoàn thành đột ngột, sau đó biểu thức gán hoàn thành đột ngột vì cùng một lý do và không có phép gán nào xảy ra.
  • Nếu không, kết quả của phép toán nhị phân được chuyển thành loại biến số bên trái, phải chuyển đổi giá trị (§5.1.13) thành bộ giá trị tiêu chuẩn thích hợp (không phải là giá trị số mũ mở rộng)) và kết quả của chuyển đổi được lưu trữ trong biến.

Đây là phần cuối cùng (được đánh dấu) tạo nên sự khác biệt.

Trong thực tế, khi bắt đầu của phần này cho thấy sự tương đương:

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.

+1

Không còn câu hỏi, danh dự của bạn. – f1sh

+2

cảm thấy tốt khi có câu hỏi đầu tiên của tôi được trả lời bởi Jon Skeet :) – Zohaib

-2

Java gây rối loạn về hoạt động và chuyển đổi liên quan đến các loại tích phân. Lời khuyên tốt nhất là sử dụng int bất cứ khi nào bạn có thể. Tránh byte/short/char, chuyển đổi chúng một cách rõ ràng thành int trước bất kỳ phép tính nào.

+2

Tại sao bạn sẽ đăng bài này 2 giờ sau khi Jon Skeet đưa ra một giải thích rất kỹ lưỡng về cách thức hoạt động của "mess"? Đôi khi sử dụng các loại khác với 'int' có ý nghĩa. – EboMike

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