2010-09-09 37 views
16

Ai đó có thể giải thích cho tôi tại sao mã sau đây biên dịch OK trong Java?Số học số nguyên trong Java với chữ char và số nguyên

char c = 'a' + 10; 

Tại sao điều này không tương đương với những điều sau đây, không biên dịch?

int i = 10; 
char c = 'a' + i; 

Java Language Specification (phần 3.10.1) khẳng định "Một số nguyên nghĩa đen là loại long nếu nó được hậu tố với một lá thư ASCII L hoặc l (ell); nếu không nó là loại int (§4.2 .1). " Phần 4.2.2 đề cập đến "Toán tử số, dẫn đến giá trị loại int hoặc long". Do đó, kết quả của sự bổ sung, theo hiểu biết của tôi, là một số int, không thể được gán cho số char biến c.

Tuy nhiên, nó biên dịch tốt (ít nhất là trong bản phát hành Sun JDK 1.6.0 17 và trong Eclipse Helios).

Thay vì một ví dụ nhân tạo có lẽ, nhưng nó được sử dụng trong một khóa học Java giới thiệu mà tôi đã dạy, và bây giờ xảy ra với tôi rằng tôi không thực sự hiểu tại sao nó hoạt động.

+3

Nhờ tất cả những ai đã trả lời. Đối với bất kỳ ai quan tâm, mục 5.2 của đặc tả ngôn ngữ (Chuyển đổi chuyển nhượng) thực tế nói "Ngoài ra, nếu biểu thức là một biểu thức liên tục (§15.28) của byte loại, ngắn, char hoặc int: ... 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 số là biểu thị trong loại biến. " – Ben

+1

Nếu bạn, giống như tôi, tình cờ vấp ngã điều này bởi vì bạn muốn biết làm thế nào để thực sự chuyển đổi một char được lập chỉ mục thành một chuỗi, ở đây bạn đi; khi 'i = 2' thì' String.valueOf ((char) ('a' + i)) 'trả về chuỗi" c ". – JohnnyLambada

Trả lời

9

'a' + 10 là một thời gian biên dịch thường xuyên biểu với giá trị của 'k', có thể khởi tạo một biến kiểu char. Điều này giống như việc gán một biến số byte với số nguyên bằng chữ trong [-128, 127]. A byte trong phạm vi [128, 255] có thể gây khó chịu hơn.

+0

Cảm ơn. Nhìn lên * biểu thức hằng số biên dịch thời gian * dẫn tôi đến phần có liên quan của đặc tả ngôn ngữ. – Ben

13

Đó là do trình biên dịch có thể kiểm tra xem nó ('a' + 10) nằm trong giới hạn của một char trong khi không thể (nói chung) kiểm tra xem 'a' + <an integer> có nằm trong giới hạn hay không.

+0

char c = 65535; biên dịch, nhưng không phải char c = 65536; – einarmagnus

+0

char là hai byte để điều này có ý nghĩa. – einarmagnus

+0

'char c = 103000;' thì không. UCS-2 ftw! –

1

Hằng số là một loại khác (tôi biết thông số kỹ thuật nói rằng 10 phải là một int, nhưng trình biên dịch không nhìn thấy theo cách đó).

Trong char c = 'a' + 10, 10 thực sự được coi là biến cố định của loại char (để nó có thể được thêm vào a). Do đó char c = char + char hoạt động.

Trong int i = 10; char c = 'a' + i; Bạn đang thêm một char đến một số nguyên (một số nguyên có thể lớn hơn nhiều so với một char, vì vậy nó chọn kiểu dữ liệu lớn hơn [int] là kết quả a.k.a: 'a' + i = int + int). Vì vậy, kết quả của việc bổ sung là một số nguyên, mà không thể phù hợp với char c.

Nếu bạn đã gắn một cách rõ ràng i làm char (ví dụ: char c = 'a' + (char)i;), nó có thể hoạt động hoặc nếu bạn làm ngược lại (ví dụ: int c = (int)'a' + i;) nó sẽ hoạt động.

+0

Tôi không nghĩ rằng nó là khá chính xác để nói rằng 10 được coi là loại char. Đúng hơn, như Tom Hawtin nói, biểu thức ''a' + 10' là hằng số * biên dịch * và do đó trình biên dịch được phép thực hiện chuyển đổi thu hẹp. Trên thực tế 'char c = 'a' + (char) i;' không hoạt động vì bên phải là kiểu 'int' và không phải là hằng số biên dịch. – Ben

3

char thực sự là số nguyên 16 bit chưa ký với phạm vi 0-65535. Vì vậy, bạn có thể chỉ định bất kỳ chữ số nguyên nào trong phạm vi đó cho một char, ví dụ: "char c = 96", kết quả là "c" giữ ký tự "a". Bạn có thể in ra kết quả bằng cách sử dụng System.out.println (c).

Đối với biểu thức liên tục ở bên tay phải của "char c = 'a' + 10", 'a' được thăng hạng thành int vì các quy tắc khuyến mãi số Java và giá trị số nguyên là 96. Sau thêm 10 vào nó, chúng ta nhận được một số nguyên nguyên 106, có thể được gán cho một char.

Phía bên tay phải của "char c = 'a' + i" không phải là biểu thức liên tục và quy tắc gán kết quả biểu thức yêu cầu một dàn diễn viên rõ ràng từ int đến char, nghĩa là "char c = (char) ('a' + i) ".

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