class文件的加载、初始化、实例化

版权声明:转载请标明来源 https://blog.csdn.net/u010652576/article/details/78449893

class文件的加载包含以下过程:加载(load class文件)-校验-准备-解析-初始化-实例化,上述过程是大致过程,具体过程可以参考:jvm class文件加载过程

看下面的代码样例:

package staticclass;

public class StaticClassTest {
    public static void main(String[] args) throws ClassNotFoundException {
        ClassLoader.getSystemClassLoader().loadClass("staticclass.User");
        System.out.println("=====");
        Class.forName("staticclass.User");
        System.out.println("+++++");
    }
}
//展示class文件的加载
class User{
    public static int age=27;
    private String name;
    static{
        System.out.println("this is static age="+age);
    }
    {
        System.out.println(" age ="+age);
    }

    public User(String name){
        System.out.println("this is constructor age="+age);
        this.name=name;
    }
    public void print(){
        System.out.println("this is "+name);
    }
    public static void printAge(){
        System.out.println("this is static printAge age="+age);
    }
}

输出内容:
=====
this is static age=27
+++++

从输出内容看到:ClasLoader把class文件进行加载,只是把相关的class文件加载到了方法区,进行了解析,并没有进行初始化,而Class.forName除了上述步骤执行了相关的初始化。

把StaticClassTest 的main方法修改如下:

public static void main(String[] args) throws ClassNotFoundException {
        Class.forName("staticclass.User");
        System.out.println("+++++");
        User u = new User("jkf");
    }

输出内容:
this is static age=27
+++++
 age =27
this is constructor age=27


从输出内容来看:Class.forName进行了初始化,而new User进行了实例化,但是static代码块,仅执行了一次,并且代码块的执行优先构造函数。

把StaticClassTest 的main方法修改如下:

public static void main(String[] args) throws ClassNotFoundException {
        int age = User.age;
        System.out.println("----------");
        User u = new User("jkf");
    }
输出内容:
this is static age=27
----------
 age =27
this is constructor age=27

从输出内容看:当我们调用类的静态属性或者方法时,仅进行了类的初始化,并不会进行实例化。

综上所述:
1 class文件的加载可以通过:ClassLoader进行加载。
2 class文件的初始化:Class.forName;调用类文件的静态方法或静态属性。
3 class文件的实例化:通过new;或者通过Class对象的newInstance()方法。
4 当然class文件的初始化包含了class文件的加载,同样class文件的实例化也包含上述两个步骤。
5 说一个有关数组的问题:

package com.classLoader;

/**class对象的加载时机**/
public class ClassLoaderTime {
    public static void main(String[] args) {
        ClassLoader[] arr = new ClassLoader[4];
        System.out.println("数组赋值");
        arr[0]=new ClassLoader();
    }
}

class ClassLoader{
    static{
        System.out.println("对象初始化");
    }
}

输出内容:
数组赋值
对象初始化

从输出内容来看,对象数组创建时,并没有加载初始化对象,而是在数组手动赋值时进行加载初始化,这是因为我们new对象了

猜你喜欢

转载自blog.csdn.net/u010652576/article/details/78449893
今日推荐