类加载过程

1.Loading

将class文件加载到内存(生成两块内容):

1.二进制放到内存的一块区域

2.生成一个class类的对象,指向了上面的内容

2.Linking

    >1.Verification(验证):验证文件是否符合JVM规定

    >2.Preparation(准备):给静态成员变量赋默认值

    >3.Resolution(解析):将类,方法,属性等符号引用解析为直接引用(转换成为内存的具体地址和指针)

3.Initializing

1.调用类初始化代码,给静态成员变量赋初始值

(成员变量赋值过程) 

public class Hello {

    //new Hello()的时候两个过程
    // 1.申请出对象的内存,成员变量count赋默认值0 
    // 2.调用构造方法,成员变量count赋初始值6
    private int count = 6;

    public Hello(){

    }
}

类加载器

类加载过程

问:为什么类加载要使用双亲委派机制?

答:为了安全 。假如直接写一个类java.lang.String,使用自定义类加载器将其load到内存,想想后果。。。

如果使用双亲委派的机制,当加载这个类的时候,首先会一层一层向上(父加载器)去查是否加载过此类,当查到最顶层Bootstrap类加载器时,发现加载过了,然后直接返回,就不会出现安全问题。

父加载器不是“类加载器的加载器”,也不是“类加载器的父类加载器”。通俗的理解他是类加载器里的一个成员变量parent对象。

双亲委派是指一个孩子向父亲的方向,然后父亲向孩子的方向的双亲委派过程。(图:类加载器)

 

手动加载一个类的class对象

Class clazz = Test4.class.getClassLoader().loadClass("com.example.springboot.demo.test.Test");

 

自定义类加载器只要重写ClassLoader的findClass方法。----------模板方法设计模式

findClass方法内部无逻辑,直接抛出ClassNotFoundException。

public class MyClassLoader extends ClassLoader {

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        File f = new File("d:/test/", name.replace(".", "/").concat(".class"));
        try {
            FileInputStream fis = new FileInputStream(f);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int b = 0;

            while ((b=fis.read()) !=0) {
                baos.write(b);
            }

            byte[] bytes = baos.toByteArray();
            baos.close();
            fis.close();//可以写的更加严谨

            return defineClass(name, bytes, 0, bytes.length);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return super.findClass(name); //throws ClassNotFoundException
    }

    public static void main(String[] args) throws Exception {
        ClassLoader myClassLoader = new MyClassLoader();
        Class clazz = myClassLoader.loadClass("com.example.springboot.demo.test.Hello");
        Class clazz1 = myClassLoader.loadClass("com.example.springboot.demo.test.Hello");

        System.out.println(clazz == clazz1);

        Hello hello = (Hello)clazz.newInstance();
        System.out.println(hello.hello());

        System.out.println(myClassLoader.getClass().getClassLoader());
        System.out.println(myClassLoader.getParent());

        System.out.println(getSystemClassLoader());
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值