java Character類源碼分析


一、使用

構建Character對象:

1 public class CharTest {
2     public static void main(String[] args) {
3         Character c1 = new Character('A');
4         Character c2 = Character.valueOf('a');
5         System.out.println(c1); // A
6         System.out.println(c2); // a
7     }
8 }

構造函數源碼:

1 @Deprecated(since="9")
2     public Character(char value) {
3         this.value = value;
4     }

可見,構造函數的形式不建議使用了。

另一種方式 Character.valueOf(),其源碼:

1  @HotSpotIntrinsicCandidate
2     public static Character valueOf(char c) {
3         if (c <= 127) { // must cache
4             return CharacterCache.cache[(int)c];
5         }
6         return new Character(c);
7     }
valueOf()方法使用了注解 @HotSpotIntrinsicCandidate,在jvm層面會有比較高效的實現。字符的十進制值小於等於127的話,將返回CharacterCache.cache[(int)c],返回事先緩存的內容。
CharacterCache是個內部類,初始化CharacterCache的時候會緩存十進制0-127這128個字符(Character對象)。
 1 private static class CharacterCache {
 2         private CharacterCache(){}
 3 
 4         static final Character cache[] = new Character[127 + 1];
 5 
 6         static {
 7             for (int i = 0; i < cache.length; i++)
 8                 cache[i] = new Character((char)i);
 9         }
10     }

二、其他方法:

1、public char charValue() 返回此 Character 對象的值。

  源碼:

1  @HotSpotIntrinsicCandidate
2     public char charValue() {
3         return value;
4     }

 使用:

 System.out.println(c1.charValue()); // A

2、public int hashCode() 返回此 Character 的哈希碼。

 源碼:

1 @Override
2     public int hashCode() {
3         return Character.hashCode(value);
4     }
5 
6     public static int hashCode(char value) {
7         // char 轉為 int
8         return (int)value;
9     }

  使用:

  System.out.println(c1.hashCode()); // 65

3、public String toString() 返回表示此 Character 值的 String 對象。結果是一個長度為 1 的字符串,其唯一組件是此 Character 對象表示的基本 char 值。

 源碼:

1 public String toString() {
2         char buf[] = {value};
3         return String.valueOf(buf);
4     }

 使用:

 System.out.println(c1.toString()); // A

4、public static String toString(char c) 返回一個表示指定 char 值的 String 對象。結果是長度為 1 的字符串,僅由指定的 char 組成。

  源碼:  

1 public static String toString(char c) {
2         return String.valueOf(c);
3     }

    使用:

 System.out.println(Character.toString('A')); // A

5、public static boolean isValidCodePoint(int codePoint)

確定指定的代碼點是否為從 0x0000 到 0x10FFFF 范圍之內的有效 Unicode 代碼點值。該方法等效於以下表達式:codePoint >= 0x0000 && codePoint <= 0x10FFFF

  源碼:

1 public static final int MIN_CODE_POINT = 0x000000;  
2 public static final int MAX_CODE_POINT = 0X10FFFF;
3 public static boolean isValidCodePoint(int codePoint) {
4         // Optimized form of:
5         //     codePoint >= MIN_CODE_POINT && codePoint <= MAX_CODE_POINT
6         int plane = codePoint >>> 16;
7         return plane < ((MAX_CODE_POINT + 1) >>> 16);
8     }

  

有效的Unicode代碼點的范圍是['\U+0000','\U+10FFFF'],即[0x000000,0x10FFFF],即[0000000, 10000 11111111 11111111],即[0, 1114111]

(MAX_CODE_POINT + 1) >>> 16, 即 0b00000000 00010001 00000000 00000000 >>> 16,等於00000000 00010001

如果codePoint大於MAX_CODE_POINT,則 (codePoint>>>16) 大於00000000 00010000。故大於MAX_CODE_POINT的值是無效的Unicode代碼點

如果codePoint小於0,即codePoint為十進制負數,則
-1
原碼:10000000 00000000 00000000 00000001
反碼:11111111 11111111 11111111 11111110
補碼:11111111 11111111 11111111 11111111
-1 >>> 16 即 11111111 11111111 11111111 11111111 >>> 16,等於11111111 11111111

-2147483648(帶符號int類型最小值)
原碼:10000000 00000000 00000000 00000000
反碼:11111111 11111111 11111111 11111111
補碼:10000000 00000000 00000000 00000000
-2147483648 >>> 16 即 10000000 00000000 00000000 00000000 >>> 16,等於 10000000 00000000

因為>>>是無符號右移動,所以如果負數(int類型),其保存值的為該負數的補碼,最高位(第16位)為符號位1,
無符號右移16位之后,得到高16位,大於00000000 00010001。故十進制負數是無效的Unicode 代碼點。

確定指定的代碼點是否為從 0x0000 到 0x10FFFF 范圍之內的有效 Unicode 代碼點值。該方法等效於以下表達式:codePoint >= 0x0000 && codePoint <= 0x10FFFF

  使用: 

  System.out.println(Character.isValidCodePoint(79)); // true
  System.out.println(Character.isValidCodePoint(-79)); // false

6、public static boolean isSupplementaryCodePoint(int codePoint) 確定指定字符(Unicode 代碼點)是否在增補字符范圍內。該方法調用以下表達式:codePoint >= 0x10000 && codePoint <= 0x10FFFF

  源碼:

1 public static final int MIN_SUPPLEMENTARY_CODE_POINT = 0x010000;
2 public static final int MAX_CODE_POINT = 0X10FFFF;
3 public static boolean isSupplementaryCodePoint(int codePoint) {
4         return codePoint >= MIN_SUPPLEMENTARY_CODE_POINT
5             && codePoint <  MAX_CODE_POINT + 1;
6     }

Unicode增補字符范圍:0x010000至0x10FFFF

  使用:

  System.out.println(Character.isSupplementaryCodePoint(65536)); // true
  System.out.println(Character.isSupplementaryCodePoint(65535)); // false

7、

public static boolean isHighSurrogate(char ch) 確定給出的 char 值是否為一個高代理項代碼單元(也稱為 前導代理項代碼單元)。這類值並不表示它們本身的字符,而被用來表示 UTF-16 編碼中的 增補字符
public static boolean isLowSurrogate(char ch) 確定給定 char 值是否一個低代理項代碼單元(也稱為 尾部代理項代碼單元)。這類值並不表示它們本身的字符,而被用來表示 UTF-16 編碼中的 增補字符
源碼:
public static final char MIN_HIGH_SURROGATE = '\uD800';
public static final char MAX_HIGH_SURROGATE = '\uDBFF';
public static boolean isHighSurrogate(char ch) {
    // Help VM constant-fold; MAX_HIGH_SURROGATE + 1 == MIN_LOW_SURROGATE
    return ch >= MIN_HIGH_SURROGATE && ch < (MAX_HIGH_SURROGATE + 1);
}

public static final char MIN_LOW_SURROGATE  = '\uDC00';
public static final char MAX_LOW_SURROGATE  = '\uDFFF';
public static boolean isLowSurrogate(char ch) {
    return ch >= MIN_LOW_SURROGATE && ch < (MAX_LOW_SURROGATE + 1);
}

高代理項范圍['\uD800', '\uDBFF'];
低代理項范圍['\uDC00', '\uDFFF']。

8、public static boolean isSurrogatePair(char high, char low) 確定指定的 char 值對是否為有效的代理項對。該方法等效於以下表達式:

源碼:

1 public static boolean isSurrogatePair(char high, char low) {
2     return isHighSurrogate(high) && isLowSurrogate(low);
3 }

9、

public static int charCount(int codePoint)
確定表示指定字符(Unicode 代碼點)所需的  char 值的數量。如果指定字符等於或大於 0x10000,則該方法返回的值為 2。否則,該方法返回的值為 1。

該方法沒有驗證指定的字符是否為一個有效的 Unicode 代碼點。如有必要,調用者必須使用 isValidCodePoint 驗證字符值。

源碼:

public static final int MIN_SUPPLEMENTARY_CODE_POINT = 0x010000;
public static int charCount(int codePoint) {
    return codePoint >= MIN_SUPPLEMENTARY_CODE_POINT ? 2 : 1;
}

  只判斷是否大於0x010000。

10、public static int toCodePoint(char high,char low) 將指定的代理項對轉換為其增補代碼點值。該方法沒有驗證指定的代理項對。如有必要,調用者必須使用 isSurrogatePair 驗證它。

源碼:
public static final int MIN_SUPPLEMENTARY_CODE_POINT = 0x010000;
public static final char MIN_LOW_SURROGATE  = '\uDC00';
public static final char MAX_HIGH_SURROGATE = '\uDBFF';
   
public static int toCodePoint(char high, char low) {
    // Optimized form of:
    // return ((high - MIN_HIGH_SURROGATE) << 10)
    //         + (low - MIN_LOW_SURROGATE)
    //         + MIN_SUPPLEMENTARY_CODE_POINT;
    return ((high << 10) + low) + (MIN_SUPPLEMENTARY_CODE_POINT - (MIN_HIGH_SURROGATE << 10) - MIN_LOW_SURROGATE);
}


優化細節:
(high - MIN_HIGH_SURROGATE) << 10 ==> (high << 10) - (MIN_HIGH_SURROGATE << 10)

待續......................

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM