JAVA高级知识
什么是类加载过程,什么是双亲委派?
我们自己的一个java文件运行,必须通过编译和类加载这两个阶段,而编译就是把java文件编译成**.class**文件,而类的加载就是通过加载器加载到JVM内存中,装载完后会得到一个class对象,我们就可以通过new来实例化这个对象。类的加载过程涉及到类加载器,JVM在运行时会产生三个类加载器,启动类加载器(BootStrap ClassLoad)、扩展类加载器(Extension ClassLoad)、应用加载器(Application ClassLoad),这三个加载组成了一个层级关系每一个类加载器分别去加载不同的jar包,除了系统自己提供的内加载器,我们自己也可以通过ClassLoad类实现自己的加载器来加载特定场所使用的class。而所谓的父委托模型就是按照类加载器的层级关系逐层进行委派,比如说我们要加载一个class文件时,首先会把这个class文件的查询和加载委派给父加载器去执行如果父加载器都不能去加载,就会自己尝试去加载这个class文件。这样设计的好处我认为有两点好处,第一个是安全性这样的一个层级关系实际代表的是一种优先级也就是所有的类加载都会优先给到BootStrap ClassLoad ,对于核心类库的类就没有办法去破坏。比如说自己写一个java.lang.String 类最终还是会交给启动类加载器,再加上每个类的加载器本身的一个作用范围那么自己写的java.lang.String就没有办法去覆盖类库中的类。第二个我认为这样的层级关系的设计,可以避免重复加载导致程序混乱的一些问题,因为如果父类加载器已经加载过了那么子加载器就没必要再去加载了。
线程池的五种状态
- RUNING 这个状态下线程池可以处理线程里的任务,也会接收任务
- SHUTDOWN 这个状态下线程池不会在接收新的任务,但是会处理已添加的任务
- STOP 这个状态下线程池不会接受新的任务也不会处理已添加的任务,会中断任务
- TIDYING 当所有的线程都已经终止线程池的状态就会变成 TIDYING,当线程池的状态变成TIDYING时会去调用terminated()方法
- TERMINATED 线程池彻底终止就会变成TERMINATED状态。线程池处于TIDYING状态时,调用terminated()就会由TIDYING转为TERMINATED。
integer为什么不能==
先上代码:
public static void main(String[] args) {
Integer num1 = 2354, num2 = 2354, num3 = 100, num4 = 100;
int num5 = 2354;
System.out.println(num1 == num2);
System.out.println(num3 == num4);
System.out.println(num5 == num1);
}
结果为:
false
true
true
num1和num2数值相等为什么是false呢,而num3和num4比较是相等是true呢?
查看Integer源码发现,Integer内部有一个静态变量缓存池IntegerCache,里面声明了一个Integer[]数组,范围-128-127,当我们声明Integer >127时 ,其实就是调用**Integer的valueOf(int i)**方法进行自动装箱,如果范围不超过-128——127,则从IntegerCache中直接获取Integer对象,如果不在范围内则会new一个新的Integer对象。
根据==和equals区别可以得到为什么要用equals比较了。
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
num1和num2数值相等为什么是false呢,而num5和num1比较是相等是true呢?
因为int 和 Integer的==比较时,integer自动拆箱成int,相当于基本类型的比较。
所以我们在使用Integer 比较相等是一定要用equals方法。