双亲委派模型
如果一个类加载器收到了一个类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。如果都不能加载则报错ClassNotFoundException。
双亲委托机制是为了保证 Java 核心库的类型安全。这种机制保证不会出现用户自己能定义java.lang.Object类等的情况。例如,用户定义了java.lang.String,那么加载这个类时最高级父类会首先加载,发现核心类中也有这个类,那么就加载了核心类库,而自定义的永远都不会加载。
类的唯一性是由类本身和类加载器共同决定的,所以同一个class文件由不同类加载器加载后,两个类是不相等的。
类加载器
类型 | 描述 |
---|---|
启动类加载器(BootStrapClassLoader) | Java_Runtime_Home/lib/*.jar 主要加载JVM自身工作需要的类,是虚拟机自身的一部分,使用C++语言实现的,其他类都是由Java语言实现的 |
扩展类加载器(ExtendsionClassLoader) | Java_Runtime_Home/lib/ext/*.jar或者 由系统变量java.ext.dir指定位置的类 |
应用程序类加载器(SystemClassLoader/ AppClassLoader) |
当前工程路径下或者 由系统变量java.classpath指定位置的类 |
自定义类加载器(UserClassLoader) | 自定义类加载器加载的类 |
1、如果用户自定义类加载器没有指定父类加载器,它的父类加载器就是应用程序类加载器,因此可以加载下面地方的类:
- Java_Runtime_Home/lib/*.jar
- Java_Runtime_Home/lib/ext/*.jar或者由系统变量java.ext.dir指定位置的类
- 当前工程路径下或者由系统变量java.classpath指定位置中类
- 自定义类加载器加载的类
2、如果用户自定义类加载器强制定义为null,它的父类加载器就是启动类加载器,因此可以加载下面的类:
- Java_Runtime_Home/lib/*.jar
- 自定义类加载器加载的类
Java程序初始化顺序
1、父类的静态变量
2、父类的静态代码块
3、子类的静态变量
4、子类的静态代码块
5、父类的非静态变量
6、父类的非静态代码块
7、父类的构造方法
8、子类的非静态变量
9、子类的非静态代码块
10、子类的构造方法
网友评论