java底层:类的加载机制,类的加载先后顺序
2014-12-02 10:17
204 查看
1,java类的加载机制
系统类加载器(system class loader)
Ⅱ
Ⅴ
扩展类加载器(extensions class loader)
Ⅱ
Ⅴ
引导类加载器(bootstrap class loader)
除了引导类加载器之外,所有的类加载器都有一个父类加载器。通过给出的 getParent()方法可以得到。对于系统提供的类加载器来说,系统类加载器的父类加载器是扩展类加载器,而扩展类加载器的父类加载器是引导类加载器;对于开发人员编写的类加载器来说,其父类加载器是加载此类加载器 Java 类的类加载器。因为类加载器 Java类如同其它的 Java 类一样,也是要由类加载器来加载的。一般来说,开发人员编写的类加载器的父类加载器是系统类加载器。类加载器通过这种方式组织起来,形成树状结构。树的根节点就是引导类加载器。
2,java类加载的先后顺序
父类的静态方法2
父类静态初始化块
子类静态初始化块
父类非静态初始化块
父类的构造方法
子类非静态初始化块
子类的构造方法
Parent类:
package ClassLoadOrder;
/*
* 1,虚拟机在首次加载Java类时,会对静态初始化块、静态成员变量、静态方法进行一次初始化;
* (类中static成员按在类中出现的顺序加载)
*
* 2,只有在调用new方法时才会创建类的实例;
*
* 3,类实例创建过程:按照父子继承关系进行初始化,
* 首先执行父类的静态初始化块、静态成员变量、静态方法块部分;
* 在执行子类的静态初始化、静态成员变量、静态方法块部分;
* 然后是父类的非静态初始化块(一对大括弧中),接着是父类的构造方法;
* 最后执行本类继承的子类的非静态初始化块,接着是子类的构造方法;
*/
public class Parent {
public Parent()
{
System.out.println("父类的构造方法");
}
{
System.out.println("父类非静态初始化块");
}
static
{
System.out.println("父类静态初始化块");
}
public static int t = parentStaticMethod2();
public static int parentStaticMethod()
{
System.out.println("父类类的静态方法");
return 10;
}
public static int parentStaticMethod2()
{
System.out.println("父类的静态方法2");
return 9;
}
@Override
protected void finalize() throws Throwable
{
// TODO Auto-generated method stub
super.finalize();
System.out.println("销毁父类");
}
}
Child类:
package ClassLoadOrder;
public class Child extends Parent {
{
System.out.println("子类非静态初始化块");
}
static
{
System.out.println("子类静态初始化块");
}
public Child()
{
System.out.println("子类的构造方法");
}
public static int childStaticMethod()
{
System.out.println("子类的静态方法");
return 1000;
}
@Override
protected void finalize() throws Throwable
{
// TODO Auto-generated method stub
super.finalize();
System.out.println("销毁子类");
}
}
Test类:
package ClassLoadOrder;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
/*Parent.parentStaticMethod();
System.out.println();
Parent.parentStaticMethod2();
System.out.println();
Parent.parentStaticMethod();*/
Child child = new Child();
//child.childStaticMethod();
//Parent parent = new Parent();
}
}
运行得到以下的结果:
父类静态初始化块
父类的静态方法2
子类静态初始化块
父类非静态初始化块
父类的构造方法
子类非静态初始化块
子类的构造方法
总结:
1,虚拟机在首次加载Java类时,会对静态初始化块、静态成员变量、静态方法进行一次初始化;
(类中static成员按在类中出现的顺序加载)
2,只有在调用new方法时才会创建类的实例;
3,类实例创建过程:按照父子继承关系进行初始化,
首先执行父类的静态初始化块、静态成员变量、静态方法块部分(静态成员执行按照代码的先后顺序执行);
在执行子类的静态初始化、静态成员变量、静态方法块部分(静态成员执行按照代码的先后顺序执行);
然后是父类的非静态初始化块(一对大括弧中),接着是父类的构造方法;
最后执行本类继承的子类的非静态初始化块,接着是子类的构造方法;
系统类加载器(system class loader)
Ⅱ
Ⅴ
扩展类加载器(extensions class loader)
Ⅱ
Ⅴ
引导类加载器(bootstrap class loader)
除了引导类加载器之外,所有的类加载器都有一个父类加载器。通过给出的 getParent()方法可以得到。对于系统提供的类加载器来说,系统类加载器的父类加载器是扩展类加载器,而扩展类加载器的父类加载器是引导类加载器;对于开发人员编写的类加载器来说,其父类加载器是加载此类加载器 Java 类的类加载器。因为类加载器 Java类如同其它的 Java 类一样,也是要由类加载器来加载的。一般来说,开发人员编写的类加载器的父类加载器是系统类加载器。类加载器通过这种方式组织起来,形成树状结构。树的根节点就是引导类加载器。
2,java类加载的先后顺序
父类的静态方法2
父类静态初始化块
子类静态初始化块
父类非静态初始化块
父类的构造方法
子类非静态初始化块
子类的构造方法
Parent类:
package ClassLoadOrder;
/*
* 1,虚拟机在首次加载Java类时,会对静态初始化块、静态成员变量、静态方法进行一次初始化;
* (类中static成员按在类中出现的顺序加载)
*
* 2,只有在调用new方法时才会创建类的实例;
*
* 3,类实例创建过程:按照父子继承关系进行初始化,
* 首先执行父类的静态初始化块、静态成员变量、静态方法块部分;
* 在执行子类的静态初始化、静态成员变量、静态方法块部分;
* 然后是父类的非静态初始化块(一对大括弧中),接着是父类的构造方法;
* 最后执行本类继承的子类的非静态初始化块,接着是子类的构造方法;
*/
public class Parent {
public Parent()
{
System.out.println("父类的构造方法");
}
{
System.out.println("父类非静态初始化块");
}
static
{
System.out.println("父类静态初始化块");
}
public static int t = parentStaticMethod2();
public static int parentStaticMethod()
{
System.out.println("父类类的静态方法");
return 10;
}
public static int parentStaticMethod2()
{
System.out.println("父类的静态方法2");
return 9;
}
@Override
protected void finalize() throws Throwable
{
// TODO Auto-generated method stub
super.finalize();
System.out.println("销毁父类");
}
}
Child类:
package ClassLoadOrder;
public class Child extends Parent {
{
System.out.println("子类非静态初始化块");
}
static
{
System.out.println("子类静态初始化块");
}
public Child()
{
System.out.println("子类的构造方法");
}
public static int childStaticMethod()
{
System.out.println("子类的静态方法");
return 1000;
}
@Override
protected void finalize() throws Throwable
{
// TODO Auto-generated method stub
super.finalize();
System.out.println("销毁子类");
}
}
Test类:
package ClassLoadOrder;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
/*Parent.parentStaticMethod();
System.out.println();
Parent.parentStaticMethod2();
System.out.println();
Parent.parentStaticMethod();*/
Child child = new Child();
//child.childStaticMethod();
//Parent parent = new Parent();
}
}
运行得到以下的结果:
父类静态初始化块
父类的静态方法2
子类静态初始化块
父类非静态初始化块
父类的构造方法
子类非静态初始化块
子类的构造方法
总结:
1,虚拟机在首次加载Java类时,会对静态初始化块、静态成员变量、静态方法进行一次初始化;
(类中static成员按在类中出现的顺序加载)
2,只有在调用new方法时才会创建类的实例;
3,类实例创建过程:按照父子继承关系进行初始化,
首先执行父类的静态初始化块、静态成员变量、静态方法块部分(静态成员执行按照代码的先后顺序执行);
在执行子类的静态初始化、静态成员变量、静态方法块部分(静态成员执行按照代码的先后顺序执行);
然后是父类的非静态初始化块(一对大括弧中),接着是父类的构造方法;
最后执行本类继承的子类的非静态初始化块,接着是子类的构造方法;
相关文章推荐
- Java杂谈3——类加载机制与初始化顺序
- java类加载的先后顺序
- 黑马程序员_一道java选择题 引发: 类的创建和自身构造方法 加载的先后顺序
- java底层加载机制
- Java杂谈3——类加载机制与初始化顺序
- Java---类加载机制,构造方法,静态变量,(静态)代码块,父类,变量加载顺序
- Java---类加载机制,构造方法,静态变量,(静态)代码块,父类,变量加载顺序
- 关于asp.net中页面事件加载的先后顺序
- JAVA程序的类加载及其反射机制
- 深入探讨Java的类加载机制
- java中架包的加载顺序
- Java类的加载顺序
- 深入探讨Java的类加载机制
- java 类加载机制
- 关于asp.net中页面事件加载的先后顺序
- Java类装载体系中的隔离性/Java 类加载机制
- 关于asp.net中页面事件加载的先后顺序
- 百无聊赖时对java类初始化先后顺序的测试
- 深入探讨Java的类加载机制
- Java 类加载机制