簡體   English   中英

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

[英]Java. Why does it work differently with english and slavic characters?

在使用Java時,我發現了一件相當奇怪的事情。 也許這是一件普通的事情,但我不明白為什么它會這樣運作。

我有這樣的代碼:

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

它工作正常,輸出“真實”。 然后我將英語B改為slavic 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

基本上“小”值緩存了盒裝表示,而“較大”值可能沒有。

JLS 5.1.7

如果被裝箱的值是一個int類型的整數文字,介於-128和127之間(§3.10.1),或者布爾文字為true或false(§3.10.3),或者是'\\ u0000'之間的字符文字'\\ u007f'包含(§3.10.4),然后讓a和b成為p的任意兩次拳擊轉換的結果。 a == b總是如此。

理想情況下,裝箱原始值總會產生相同的參考。 實際上,使用現有的實現技術可能不可行。 上面的規則是一種務實的妥協,要求將某些共同的值總是裝入無法區分的對象中。 實現可以懶惰地或急切地緩存這些。 對於其他值,該規則不允許對程序員的盒裝值的身份進行任何假設。 這允許(但不要求)共享部分或全部這些引用。 請注意,允許共享long類型的整數文字,但不是必需的。

這確保了在大多數常見情況下,行為將是期望的行為,而不會造成過度的性能損失,尤其是在小型設備上。 例如,較少內存限制的實現可以緩存所有charshort值,以及-32K到+ 32K范圍內的intlong值。

關於“ \ and \\ u007f`之間的字符文字”的部分保證將緩存盒裝的ASCII字符,但不保留非ASCII的盒裝字符。

當你這樣做

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

類似

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM