Java的.为什么英语和斯拉夫字符的工作方式不同?

use*_*103 7 java compare character object

在使用Java时,我发现了一件相当奇怪的事情.也许这是一件普通的事情,但我不明白为什么它会这样运作.

我有这样的代码:

Character x = 'B';
Object o = x;
System.out.println(o == 'B');
Run Code Online (Sandbox Code Playgroud)

它工作正常,输出"真实".然后我将英语B改为slavic B(Б):

Character x = '?';
Object o = x;
System.out.println(o == '?');
Run Code Online (Sandbox Code Playgroud)

现在输出是"假的".怎么会?顺便说一句,如果我直接将x变量与'Б'进行比较,输出仍然是"真",但是当我通过对象执行它时它的工作方式不同.

有人可以解释一下这种行为吗?

Jon*_*eet 8

没有拳击 - 只使用char- 你会没事的.同样,如果你使用equals而不是==,你会没事的.问题是您正在比较使用的盒装值的引用==,它仅检查引用标识.由于自动拳击的工作方式,你看到了不同之处.你可以看到同样的事情Integer:

Object x = 0;
Object y = 0;
System.out.println(x == y); // Guaranteed to be true

Object x = 10000;
Object y = 10000;
System.out.println(x == y); // *May* be true
Run Code Online (Sandbox Code Playgroud)

基本上"小"值缓存了盒装表示,而"较大"值可能不缓存.

JLS 5.1.7:

如果被装箱的值是一个int介于-128和127之间的整数字面值(§3.10.1),或者布尔文字是真或假(§3.10.3),或者是'\ u0000'和'之间的字符文字\ u007f'包容性(§3.10.4),然后让a和b成为p的任意两次拳击转换的结果.a == b总是如此.

理想情况下,装箱原始值总会产生相同的参考.实际上,使用现有的实现技术可能不可行.上面的规则是一种务实的妥协,要求将某些共同的值总是装入无法区分的对象中.实现可以懒惰地或急切地缓存这些.对于其他值,该规则不允许对程序员的盒装值的身份进行任何假设.这允许(但不要求)共享部分或全部这些引用.请注意,long要共享类型的整数文字,但不是必需的.

这确保了在大多数常见情况下,行为将是期望的行为,而不会造成过度的性能损失,尤其是在小型设备上.较少的内存限制的实施方式中可能,例如,高速缓存的所有charshort价值,以及intlong值中的-32K至+ 32K的范围内.

关于" \u0000 and\ u007f` 之间的字符文字"的部分保证将缓存盒装的ASCII字符,但不保留非ASCII的盒装字符.