Object
1. getClass、hashCode、notify、wait、clone都是native方法,使用C实现;
2. equals默认是使用地址比较:return (this == obj);
3. toString默认实现:getClass().getName() + "@" + Integer.toHexString(hashCode());
4. Object是所有类的父类,但类并不需要显示的extends Object,原因:虚拟机运行二进制代码时,当遇到没有父类的类时,就会自动将这个类看成是Object类的子类,而IDE做了智能处理才能联想出Object的方法;
String
1. 内部使用Char数组保存字符串值:private final char value[],length()即是返回数组长度,final表明每次都返回新的;
2. 一些基本操作都是操作Char数组,比如length、charAt、toCharArray(返回数组拷贝)等方法;
3. 判断字符串相等equals:先判断地址是否相等(==)、再判断是否字符串、再判断长度、再逐个字符比较;
4. 重写了Object的toString、equals、hashcode方法;
5. hashcode实现:字符串为空返回0,否则逐个字符计算:31 * h + char[i],使用31是因为31是质数计算出来哈希码不大不小,同时可以将惩罚转成位移提升性能;
AbstractStringBuilder
1. 内部使用Char数组保存字符串值: char value[],和String不同的是没有final;
2. append方法每次都是使用新容量拷贝新数组Arrays.copyOf,再把字符串放到数组最后,如果是null则附加“null”字符串;
3. 对字符串的操作都是使用System.arraycopy拷贝新数组,借此实现可变长字符串;区别于String
StringBuffer
1. 继承AbstractStringBuilder,默认初始化容量为16,若用字符串初始化则容量为字符串长度+16;
2. 各种方法都加了synchronized用以保证线程安全;
3. 覆写了toString方法,内部用char[] toStringCache保存了字符串缓存,每次更改时清空缓存;
StringBuilder
1. 继承AbstractStringBuilder,默认初始化容量为16,若用字符串初始化则容量为字符串长度+16;同StringBuffer
2. 各种方法都没有加synchronized,所以线程不安全;区别于StringBuffer
3. 覆写了toString方法,直接new了String返回,没有使用缓存;区别于StringBuffer
Boolean
1. final类,不能继承,parseBoolean(String s),字符串非空且忽略大小写与true相等时返回true;
2. hashCode方法直接返回了2个固定值:value ? 1231 : 1237,原因:1231和1237是两个比较大的素数,与其他变量计算hash时可以尽量避免hash冲突,而采用1231和1237更大程度的原因是作者个人爱好;
3. getBoolean实现是根据字符串找系统属性:parseBoolean(System.getProperty(name)),这点要注意
Byte
1. final类,继承Number,内部维护ByteCache私有静态类,初始化数组(下标即对应值),valueOf(byte b)即是取数组对应下标的值;
2. toString调用的是Integer的实现,hashCode直接返回当前值;
Short
1. final类,继承Number,内部维护ShortCache私有静态类(大小范围同byteCache),初始化数组(下标即对应值),valueOf(short b)先判断是否在范围内,再则返回缓存,否则new返回;
2. toString调用的是Integer的实现,hashCode直接返回当前值;
Integer
1. final类,继承Number,getInteger根据字符串找系统属性,hashCode直接返回当前值;
2. toString实现较复杂,先根据数据大小分区间获取字符串长度,再逐个处理;
3. valueOf如果在-128-127之间直接返回缓存数组中的值,否则new返回;
Long
1. final类,继承Number,getLong根据字符串找系统属性,hashCode经过了位运算;
2. toString实现较复杂,先通过循环比较获取字符串长度,再逐个处理;
Double Float
1. final类,继承Number,没有getFloat getDouble方法,根据字符串找系统属性,hashCode实现较复杂;
2. toString方法调用了sun.misc包实现;
Thread
1. 实现Runable接口,第一步执行registerNatives本地方法,将本地方法名称和真正的C实现方法做映射注册,即注册一些本地方法供 Thread 类使用;
2. sleep(long millis, int nanos)方法不会纳秒睡眠,而是一定条件下微秒加1,纳秒过小时直接睡微秒;
3. 这些实现都是本地方法:currentThread、yield、sleep、isInterrupted、isAlive、suspend等基本都是;
4. 使用Thread(Runnable target)构造函数生成线程时:线程名称自动命名Thread-自增序号,线程组、daemon属性、优先级等其他属性都和父线程一样,线程ID:tid采用自增序列;
5. clone():覆写了克隆方法,直接抛不支持异常,线程对象不能克隆;
6. Thread构造方法的stackSize参数:默认为0,由JVM自动处理,有些JVM会忽略掉这个参数,手动设置这个参数以及这个参数是否生效取决于平台,如果设置小了,JVM能支持同时存活更多的线程,反之更少;
7. start()方法:有synchronized修饰,并且会判断线程状态为未启动才会执行,同一线程不能启动多次,完成后也不能重新启动;调用本地方法启动线程:start0();
8. run()方法实现:直接调用了构造函数传进来的Runable的run方法,否则不做任何处理,子类应该覆盖该方法;
9. setPriority():如果设置优先级大于线程组的优先级则设置为线程组的;
10. Thread构造方法的ThreadGroup参数:一个线程必然有线程组,默认为创建该线程的线程所在的线程组,即main;
11. 覆写了toString方法:"Thread[" + getName() + "," + getPriority() + "," + group.getName() + "]";
12. 定义了线程状态枚举:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED
13. join()实现原理:
1)方法通过synchronized修饰,需要持有线程对象锁;
2)底层通过wait实现,不断循环判断当前线程是否alive,alive则wait(此处循环是因为其他地方可能notify导致提前退出执行了主线程);
3)wait会释放当前持有的线程对象锁,当前线程执行完成后JVM会调用notifyall,从而使调用线程重新获得锁,继而往下执行;
4)wait的线程是主线程不是调用线程,因为此处调用相当于普通对象方法,是在主线程中调用的wait,所以是主线程等待;
14. 重要的私有变量:线程名称name、优先级priority、守护线程标识daemon、执行对象Runnable target、线程组ThreadGroup group、本地变量threadLocals、线程堆栈大小:stackSize、线程ID:tid、线程整形状态:threadStatus、线程名称序列号生成:threadInitNumber、线程ID序列号生成:threadSeqNumber
ThreadLocal
1. get()方法实现:获取当前线程并获取threadLocals变量并获取值,取不到就调用setInitialValue返回初始值;
2. 内部维护内部静态类ThreadLocalMap,是一种类似java.util.HashMap的数据结构,通过自定义Entry数组存放所有ThreadLocal对象及值,通过hash检索;
3. ThreadLocalMap.Entry的成员ThreadLocal>类型的成员是一个弱引用,当没有强引用引用时会清空ThreadLocal,但是Entry对象还在,即Entry的key为空,如果线程无法结束则Entry一直在而造成内存泄漏,建议手动调用ThreadLocal的remove方法删除;
Throwable
1. 关键属性:detailMessage异常详细信息、Throwable cause表示当前异常由那个Throwable引起、StackTraceElement[] stackTrace异常轨迹的数组;
2. printStackTrace()实现:调用当前对象的toString方法,获取异常轨迹数组循环打印,递归的打印出起因对象的信息 ;
Error Exception
1. 继承Throwable,本身只有几个构造函数都是直接继承父类实现,没有其他实现方法;
RuntimeException
1. 继承Exception,本身只有几个构造函数都是直接继承父类实现,没有其他实现方法,其他各个异常类实现也是如此;
Class
1. Final类,不提供构造函数,只有一个私有的private Class(ClassLoader loader);
2. forName方法调用了本地方法forName0;
ClassLoader
1. loadClass实现:检查要加载的类是不是已经被加载了(本地方法),再递归调用父类的类加载器,若父类是boot则从boot加载器找,最后找自己的加载器;(即双亲委托机制)
2. 通过集成ClassLoader实现自己的类加载器;
Void
1. void 是一种基本数据类型,而 Void 是 void 封装类型,但不同于Integer 之于 int,Void不可实例化,没有内置的类型实例,也没有可用的字面值;
2. Void 一个可用的地方是反射判断方法的返回值时:if(m.getReturnType().equals(Void.TYPE))
System
1. 这些都是本地方法:currentTimeMillis、nanoTime、setOut、setIn、setErr、arraycopy、initProperties;
2. lineSeparator换行符从系统属性中获取:props.getProperty("line.separator");
Runtime
1. 每个Java应用程序都有一个Runtime类实例,它允许应用程序与运行应用程序的环境进行交互。可以从getRuntime方法获取当前运行时;
2. 这些方法都是本地实现:gc、maxMemory;