Khi thêm 'a' + 'b'
nó tạo ra 195. Là kiểu dữ liệu đầu ra char
hay int
?
Khi thêm 'a' + 'b'
nó tạo ra 195. Là kiểu dữ liệu đầu ra char
hay int
?
Câu trả lời:
Kết quả của việc thêm ký tự Java, quần short hoặc byte là một int :
Đặc tả ngôn ngữ Java về Quảng cáo số nhị phân :
- Nếu bất kỳ toán hạng nào thuộc loại tham chiếu, chuyển đổi mở hộp (§5.1.8) được thực hiện. Sau đó:
- Nếu một trong hai toán hạng thuộc loại double, toán hạng kia được chuyển thành double.
- Ngược lại, nếu một trong hai toán hạng là kiểu float, thì toán hạng còn lại sẽ được chuyển thành float.
- Ngược lại, nếu một trong hai toán hạng thuộc loại dài, toán hạng còn lại được chuyển thành dài.
- Nếu không, cả hai toán hạng đều được chuyển đổi thành kiểu int.
Nhưng hãy lưu ý những gì nó nói về các toán tử gán ghép (như + =) :
Kết quả của phép toán nhị phân được chuyển đổi thành kiểu của biến bên trái ... và kết quả của phép chuyển đổi được lưu trữ vào biến.
Ví dụ:
char x = 1, y = 2;
x = x + y; // compile error: "possible loss of precision (found int, required char)"
x = (char)(x + y); // explicit cast back to char; OK
x += y; // compound operation-assignment; also OK
Nói chung, bạn có thể tìm ra loại kết quả là truyền nó tới một Đối tượng và hỏi nó thuộc lớp nào:
System.out.println(((Object)('a' + 'b')).getClass());
// outputs: class java.lang.Integer
Nếu bạn quan tâm đến hiệu suất, hãy lưu ý rằng mã bytecode của Java thậm chí không có các hướng dẫn dành riêng cho số học với các kiểu dữ liệu nhỏ hơn. Ví dụ, để thêm vào, có các hướng dẫn iadd
(cho ints), ladd
(cho longs), fadd
(cho float), dadd
(cho double), và thế là xong. Để mô phỏng x += y
với các kiểu nhỏ hơn, trình biên dịch sẽ sử dụng iadd
và sau đó bằng không các byte phía trên của int bằng cách sử dụng một lệnh như i2c
("int to char"). Nếu CPU gốc có hướng dẫn dành riêng cho dữ liệu 1 byte hoặc 2 byte, thì máy ảo Java sẽ tối ưu hóa cho dữ liệu đó tại thời điểm chạy.
Nếu bạn muốn nối các ký tự dưới dạng một Chuỗi thay vì diễn giải chúng dưới dạng kiểu số, có rất nhiều cách để thực hiện điều đó. Cách dễ nhất là thêm một Chuỗi trống vào biểu thức, bởi vì việc thêm một ký tự và một Chuỗi dẫn đến một Chuỗi. Tất cả các biểu thức này dẫn đến Chuỗi "ab"
:
'a' + "" + 'b'
"" + 'a' + 'b'
(điều này hoạt động vì "" + 'a'
được đánh giá đầu tiên; nếu ""
ở cuối thay vào đó bạn sẽ nhận được "195"
)new String(new char[] { 'a', 'b' })
new StringBuilder().append('a').append('b').toString()
String.format("%c%c", 'a', 'b')
Các phép toán số học nhị phân trên char
và byte
(và short
) thăng hạng thành int
- JLS 5.6.2.
Bạn có thể muốn tìm hiểu các biểu thức sau đây về char
.
char c='A';
int i=c+1;
System.out.println("i = "+i);
Điều này hoàn toàn hợp lệ trong Java và trả về 66
, giá trị tương ứng của ký tự (Unicode) của c+1
.
String temp="";
temp+=c;
System.out.println("temp = "+temp);
Điều này quá hợp lệ trong Java và biến kiểu Chuỗi temp
tự động chấp nhận c
kiểu char và tạo ra temp=A
trên bảng điều khiển.
Tất cả các câu lệnh sau đây cũng hợp lệ trong Java!
Integer intType=new Integer(c);
System.out.println("intType = "+intType);
Double doubleType=new Double(c);
System.out.println("doubleType = "+doubleType);
Float floatType=new Float(c);
System.out.println("floatType = "+floatType);
BigDecimal decimalType=new BigDecimal(c);
System.out.println("decimalType = "+decimalType);
Long longType=new Long(c);
System.out.println("longType = "+longType);
Mặc dù c
là một kiểu char
, nhưng nó có thể được cung cấp mà không có lỗi trong các hàm tạo tương ứng và tất cả các câu lệnh trên đều được coi là câu lệnh hợp lệ. Chúng tạo ra các đầu ra tương ứng như sau.
intType = 65
doubleType = 65.0
floatType = 65.0
decimalType = 65
longType =65
char
là một kiểu tích phân số nguyên thủy và như vậy phải tuân theo tất cả các quy tắc của những con thú này bao gồm chuyển đổi và thăng hạng. Bạn sẽ muốn đọc về điều này và JLS là một trong những nguồn tốt nhất cho việc này: Chuyển đổi và Quảng cáo . Đặc biệt, hãy đọc đoạn ngắn về "5.1.2 Mở rộng Chuyển đổi Nguyên thủy".
Trình biên dịch Java có thể hiểu nó là một trong hai.
Kiểm tra bằng cách viết chương trình và tìm lỗi trình biên dịch:
public static void main(String[] args) {
int result1 = 'a' + 'b';
char result2 = 'a' + 'b';
}
Nếu đó là một ký tự, thì dòng đầu tiên sẽ cho tôi lỗi và dòng thứ hai thì không. Nếu đó là một int, thì điều ngược lại sẽ xảy ra.
Tôi đã biên dịch nó và tôi đã ..... KHÔNG CÓ LỖI. Vì vậy, Java chấp nhận cả hai.
Tuy nhiên, khi tôi in chúng, tôi nhận được:
int: 195
char: Ã
Điều gì sẽ xảy ra khi bạn làm:
char result2 = 'a' + 'b'
một chuyển đổi ngầm được thực hiện (một "chuyển đổi thu hẹp nguyên thủy" từ int sang char ).
Theo quy tắc thăng hạng nhị phân , nếu không có toán hạng nào là kép, float hoặc long, thì cả hai đều được thăng thành int. Tuy nhiên, tôi thực sự khuyên bạn không nên coi kiểu char là số, kiểu đó làm mất mục đích của nó.
char
như một giá trị số hoàn toàn nằm trong mục đích của nó, đó là lý do tại sao JLS dành rất nhiều chi tiết cho việc sử dụng như vậy.
Mặc dù bạn đã có câu trả lời chính xác (được tham chiếu trong JLS), đây là một đoạn mã để xác minh rằng bạn nhận được một int
khi thêm hai char
s.
public class CharAdditionTest
{
public static void main(String args[])
{
char a = 'a';
char b = 'b';
Object obj = a + b;
System.out.println(obj.getClass().getName());
}
}
Đầu ra là
java.lang.Integer
int
và Integer
không giống nhau. Một xác minh thuyết phục hơn là cố gắng gán a + b
cho một int
biến hoặc một char
biến. Sau đó đưa ra một lỗi biên dịch có hiệu lực là "bạn không thể gán một int
cho một char
".
char
được biểu diễn dưới dạng Unicode
giá trị và trong đó giá trị Unicode được biểu thị \u
bằng Hexadecimal
giá trị theo sau .
Là bất kỳ phép toán số học nào trên char
các giá trị được thăng cấp int
, do đó, kết quả của 'a' + 'b'
được tính như
1.) Áp dụng các Unicode
giá trị trên tương ứng char
bằng cách sử dụngUnicode Table
2.) Áp dụng chuyển đổi Hệ thập lục phân sang Hệ thập phân và sau đó thực hiện thao tác trên Decimal
các giá trị.
char Unicode Decimal
a 0061 97
b 0062 98 +
195
Thí dụ
0061
(0 * 16 3 ) + (0 * 16 2 ) + (6 * 16 1 ) + (1 * 16 0 )
(0 * 4096) + (0 * 256) + (6 * 16) + (1 * 1)
0 + 0 + 96 + 1 = 97
0062
(0 * 16 3 ) + (0 * 16 2 ) + (6 * 16 1 ) + (2 * 16 0 )
(0 * 4096) + (0 * 256) + (6 * 16) + (2 * 1)
0 + 0 + 96 + 2 = 98
Vì thế 97 + 98 = 195
Ví dụ 2
char Unicode Decimal
Ջ 054b 1355
À 00c0 192
--------
1547 +
1163 -
7 /
260160 *
11 %
Trong khi câu trả lời của Boann là đúng, có một sự phức tạp áp dụng cho trường hợp các biểu thức hằng khi chúng xuất hiện trong ngữ cảnh gán .
Hãy xem xét các ví dụ sau:
char x = 'a' + 'b'; // OK
char y = 'a';
char z = y + 'b'; // Compilation error
Điều gì đang xảy ra? Họ có ý nghĩa giống nhau phải không? Và tại sao việc gán một int
cho một char
trong ví dụ đầu tiên là hợp pháp ?
Khi một biểu thức hằng xuất hiện trong ngữ cảnh gán, trình biên dịch Java sẽ tính giá trị của biểu thức và xem nó có nằm trong phạm vi của kiểu mà bạn đang gán hay không. Nếu đúng như vậy, thì một chuyển đổi nguyên thủy thu hẹp ngầm được áp dụng.
Trong ví dụ đầu tiên, 'a' + 'b'
là một biểu thức hằng và giá trị của nó sẽ phù hợp với a char
, vì vậy trình biên dịch cho phép thu hẹp ngầm định int
kết quả biểu thức thành a char
.
Trong ví dụ thứ hai, y
là một biến vì vậy y + 'b'
KHÔNG phải là một biểu thức hằng. Vì vậy, mặc dù Blind Freddy có thể thấy rằng giá trị sẽ phù hợp, trình biên dịch KHÔNG cho phép thu hẹp ngầm định nào và bạn gặp lỗi biên dịch nói rằng int
không thể gán giá trị cho a char
.
Có một số cảnh báo khác về thời điểm cho phép chuyển đổi nguyên thủy thu hẹp ngầm định trong ngữ cảnh này; xem JLS 5.2 và JLS 15.28 để biết chi tiết đầy đủ.
Phần sau giải thích chi tiết các yêu cầu đối với một biểu thức hằng . Nó có thể không phải là những gì bạn có thể nghĩ. (Ví dụ: chỉ khai báo y
là final
không giúp ích gì.)
char
thì giá trị của'a' + 'b'
sẽ không được195
nhưng'Ã'