java Character类源码分析
一、使用
构建Character对象:
public class CharTest {
public static void main(String[] args) {
Character c1 = new Character('A');
Character c2 = Character.valueOf('a');
System.out.println(c1); // A
System.out.println(c2); // a
}
}
构造函数源码:
@Deprecated(since="")
public Character(char value) {
this.value = value;
}
可见,构造函数的形式不建议使用了。
另一种方式 Character.valueOf(),其源码:
@HotSpotIntrinsicCandidate
public static Character valueOf(char c) {
if (c <= 127) { // must cache
return CharacterCache.cache[(int)c];
}
return new Character(c);
}
valueOf()方法使用了注解 @HotSpotIntrinsicCandidate,在jvm层面会有比较高效的实现。字符的十进制值小于等于127的话,将返回CharacterCache.cache[(int)c],返回事先缓存的内容。
CharacterCache是个内部类,初始化CharacterCache的时候会缓存十进制0-127这128个字符(Character对象)。
private static class CharacterCache {
private CharacterCache(){}
static final Character cache[] = new Character[127 + 1];
static {
for (int i = 0; i < cache.length; i++)
cache[i] = new Character((char)i);
}
}
二、其他方法:
1、public char charValue() 返回此 Character 对象的值。
源码:
@HotSpotIntrinsicCandidate
public char charValue() {
return value;
}
使用:
System.out.println(c1.charValue()); // A
2、public int hashCode() 返回此 Character 的哈希码。
源码:
@Override
public int hashCode() {
return Character.hashCode(value);
} public static int hashCode(char value) {
// char 转为 int
return (int)value;
}
使用:
System.out.println(c1.hashCode()); // 65
3、public String toString() 返回表示此 Character 值的 String 对象。结果是一个长度为 1 的字符串,其唯一组件是此 Character 对象表示的基本 char 值。
源码:
public String toString() {
char buf[] = {value};
return String.valueOf(buf);
}
使用:
System.out.println(c1.toString()); // A
4、public static String toString(char c) 返回一个表示指定 char 值的 String 对象。结果是长度为 1 的字符串,仅由指定的 char 组成。
源码:
public static String toString(char c) {
return String.valueOf(c);
}
使用:
System.out.println(Character.toString('A')); // A
5、public static boolean isValidCodePoint(int codePoint)
确定指定的代码点是否为从 0x0000 到 0x10FFFF 范围之内的有效 Unicode 代码点值。该方法等效于以下表达式:codePoint >= 0x0000 && codePoint <= 0x10FFFF
源码:
public static final int MIN_CODE_POINT = 0x000000;
public static final int MAX_CODE_POINT = 0X10FFFF;
public static boolean isValidCodePoint(int codePoint) {
// Optimized form of:
// codePoint >= MIN_CODE_POINT && codePoint <= MAX_CODE_POINT
int plane = codePoint >>> 16;
return plane < ((MAX_CODE_POINT + 1) >>> 16);
}
有效的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
源码:
public static final int MIN_SUPPLEMENTARY_CODE_POINT = 0x010000;
public static final int MAX_CODE_POINT = 0X10FFFF;
public static boolean isSupplementaryCodePoint(int codePoint) {
return codePoint >= MIN_SUPPLEMENTARY_CODE_POINT
&& codePoint < MAX_CODE_POINT + 1;
}
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 值对是否为有效的代理项对。该方法等效于以下表达式:
源码:
public static boolean isSurrogatePair(char high, char low) {
return isHighSurrogate(high) && isLowSurrogate(low);
}
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)
待续......................
java Character类源码分析的更多相关文章
- Java Properties类源码分析
一.Properties类介绍 java.util.Properties继承自java.util.Hashtable,从jdk1.1版本开始,Properties的实现基本上就没有什么大的变动.从ht ...
- 【JAVA】ThreadLocal源码分析
ThreadLocal内部是用一张哈希表来存储: static class ThreadLocalMap { static class Entry extends WeakReference<T ...
- 细说并发5:Java 阻塞队列源码分析(下)
上一篇 细说并发4:Java 阻塞队列源码分析(上) 我们了解了 ArrayBlockingQueue, LinkedBlockingQueue 和 PriorityBlockingQueue,这篇文 ...
- List 接口以及实现类和相关类源码分析
List 接口以及实现类和相关类源码分析 List接口分析 接口描述 用户可以对列表进行随机的读取(get),插入(add),删除(remove),修改(set),也可批量增加(addAll),删除( ...
- Java split方法源码分析
Java split方法源码分析 public String[] split(CharSequence input [, int limit]) { int index = 0; // 指针 bool ...
- 【Java】HashMap源码分析——常用方法详解
上一篇介绍了HashMap的基本概念,这一篇着重介绍HasHMap中的一些常用方法:put()get()**resize()** 首先介绍resize()这个方法,在我看来这是HashMap中一个非常 ...
- 【Java】HashMap源码分析——基本概念
在JDK1.8后,对HashMap源码进行了更改,引入了红黑树.在这之前,HashMap实际上就是就是数组+链表的结构,由于HashMap是一张哈希表,其会产生哈希冲突,为了解决哈希冲突,HashMa ...
- java中List接口的实现类 ArrayList,LinkedList,Vector 的区别 list实现类源码分析
java面试中经常被问到list常用的类以及内部实现机制,平时开发也经常用到list集合类,因此做一个源码级别的分析和比较之间的差异. 首先看一下List接口的的继承关系: list接口继承Colle ...
- Java并发编程笔记之Unsafe类和LockSupport类源码分析
一.Unsafe类的源码分析 JDK的rt.jar包中的Unsafe类提供了硬件级别的原子操作,Unsafe里面的方法都是native方法,通过使用JNI的方式来访问本地C++实现库. rt.jar ...
随机推荐
- db4o这个对象数据库有很多优点,但为什么不是很火? 大家有没有用过db4o的?
没有主键的概念(因为对象的内存地址,或者引用就能标志一个对象了).因而外界想指向一个具体的对象就比较困难(比如本页的url里的1079505). 激活/保存层次的问题.获取一个对象,它的字段引用了其它 ...
- java8 stream编程
说明:这是基于同事的培训材料做的练习,记录下来,以作日后自己coding分析和改进 1.准备 pom.xml <dependency> <groupId>org.apache. ...
- 用户tokenId
tokenId表示为:用户登录到成功后,服务端分配给客户端的令牌号,同时下发tokenId的过期时间.下次用户直接持有tokenId,在其过期时间内均可跳过用户登录步骤,直接请求其他服务操作.如果to ...
- gts测试流程
测试目的: 用于检测你做的Android gms包是否满足兼容性要求,通俗点说,gms包,就是Google自己的apk,提供基础服务,例如YouTube.playstore等. 测试前提: 1.发货u ...
- 根据对象属性查找对象或者数组(根据对象属性查找某数组内符合该条件的对象,数组内对象属性check为true的对象,存放到数组内) 滚动轴样式
1.根据对象属性查找某数组内符合该条件的对象. optionComwords:[ {optionName:"名称1", optionCode: '1'}, {optionNam ...
- Java程序的运行过程,以及Java为什么能够跨平台
Java程序运行机制 Java的运行主要分两步:先编译再解释执行 (1)先通过“编译器”将Java源程序(.java)编译成Java字节码文件(.class) (2)通过不同的虚拟机(JVM)将字节 ...
- linux rz上传-sz下载
yum install lrzsz -y rz 上传文件 不能传目录 如果要传目录需要打包成文件再上传 需要往哪里传东西,先进入哪个目录 rz -y 上传覆盖 sz -y 文件名 ...
- nginx 事件机制原理
事件驱动模型是Nginx服务器保障完整功能和具有良好性能的重要机制之一. 事件驱动模型概述 实际上,事件驱动并不是计算机编程领域的专业词汇,它是一种比较古老的响应事件的模型,在计算机编程.公共关系.经 ...
- Spring框架学习总结
一.Spring概述 1.什么是Spring? Spring是一个优秀轻量级的框架,是Java中使用最多的框架,Spring框架具有轻量.控制反转.面向切面.容器.框架.MVC的特点. 2.Sprin ...
- EML文件(MIME邮件)格式分析
电子邮件普遍遵循的邮件技术规范.MIME邮件由邮件头和邮件体两部分组成.邮件头包括:标题,送信人,收信人,创建日期,邮件体内容类型和邮件体编码方式等内容.邮件体包括:正文,超文本,内嵌数据和附件等内容 ...