Java。为什么它与英语和斯拉夫语字符有所不同?
我在使用Java时发现了一个很奇怪的事情。也许这是一件普通的事情,但我不明白为什么它以这种方式工作。Java。为什么它与英语和斯拉夫语字符有所不同?
我有这样的代码:
Character x = 'B';
Object o = x;
System.out.println(o == 'B');
它工作正常,输出为“真”。 然后我改变英语B至斯拉夫B(Б):
Character x = 'Б';
Object o = x;
System.out.println(o == 'Б');
现在的输出为 “假”。怎么来的? 顺便说一下,如果我直接将x变量与'Б'进行比较,那么输出结果仍然是“真”,但是当我通过对象执行时,它的工作方式不同。
任何人都可以解释这种行为吗?
没有拳击 - 只使用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
基本上都是“小”值已缓存的盒装表示,而“较大”的值可能不是。
如果值p被装箱是-128到127之间的字面
int
类型的整数包容(§3.10.1)或布尔值真或假(§3.10。 3)或'\ u0000'和'\ u007f'之间的字符字面值(§3.10.4),则让a和b为p的任意两次装箱转换的结果。情况总是如此,a == b。理想情况下,装箱原始值总是会产生相同的参考。实际上,使用现有的实现技术可能不可行。上述规则是一种务实的妥协,要求某些共同的价值观总是被装箱成不可区分的对象。实现可能会缓存这些,懒惰或热切。对于其他值,该规则不允许对程序员的盒装值的身份进行任何假设。这允许(但不要求)共享这些引用的一部分或全部。请注意,允许共享
long
类型的整数文字,但不是必需的。这可以确保在大多数情况下,行为将成为所需的行为,而不会对性能造成不必要的损失,特别是在小型设备上。例如,较少的内存有限的实现可能会缓存所有值为-32K到+ 32K的所有
char
和short
值,以及int
和long
值。
关于“\u0000 and
\ u007f`之间的字符文字”的部分保证了盒装ASCII字符将被缓存,但不是非ASCII盒装字符。
当你做
Character x = 'B'
2: invokestatic #16 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
用于缓存
这种方法将范围 '\ u0000的' 永远的缓存值 '\ u007F' (含),并且可以缓存该范围之外的其他值。
public static Character valueOf(char c) {
if(c <= 127) { // must cache
return CharacterCache.cache[(int)c];
}
return new Character(c);
}
类似