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

时间:2014-09-10 16:46:45

标签: java object compare character

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

我有这样的代码:

Character x = 'B';
Object o = x;
System.out.println(o == 'B');

它工作正常,输出为“true”。 然后我将英语B改为slavic B(Б):

Character x = 'Б';
Object o = x;
System.out.println(o == 'Б');

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

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

2 个答案:

答案 0 :(得分: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 看到相同的内容:

int

基本上“小”值缓存了盒装表示,而“较大”值可能不缓存。

来自JLS 5.1.7

  

如果被装箱的值是一个类型为long的整数文字,介于-128和127之间(§3.10.1),或者布尔文字为true或false(§3.10.3),或者是一个字符在'\ u0000'和'\ u007f'之间包含文字(§3.10.4),然后让a和b为p的任意两次拳击转换的结果。 a == b。

总是如此      

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

     

这确保了在大多数情况下,行为将是所需的行为,而不会造成过度的性能损失,尤其是在小型设备上。例如,较少内存限制的实现可以缓存所有shortint值,以及-32K到+ 32K范围内的long\u0000 and值。

关于“{{1}} \ u007f`之间的字符文字”的部分保证将缓存盒装的ASCII字符,但不保留非ASCII的盒装字符。

答案 1 :(得分:2)

当你做

Character x = 'B' 

它调用Character.valueOf(C)

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);
}

<强>类似