ClassLoader如何加载类到虚拟机并获取其对象

2019-12-09  本文已影响0人  付凯强

0. 序言

1. 一般情况下

package com.bytedance;

public class Plus {

    public int plus(int a,int b){
        return a + b;
    }
}
package com.bytedance;

public class Test {

    public static void main(String[] args) {
        int result = new Plus().plus(1, 2);
        System.out.println(result);
    }
}

2. 实现类在单独的jar中

2.1 编译通过

package com.bytedance;

public interface IPlus {
    int plus(int a,int b);
}
package com.bytedance;

class FatherFactory {
    private static FatherFactory sFatherFactoryInstance;
    public static FatherFactory getSingleton() {
        if (sFatherFactoryInstance == null){

        }
        return sFatherFactoryInstance;
    }
    
    public IPlus getPlusInstance(){
        return null;
    }
}
package com.bytedance;

public class Test {
    public static void main(String[] args) {
        FatherFactory fatherFactory = (SonFactory)FatherFactory.getSingleton();
        int result = fatherFactory.getPlusInstance().plus(1,2);
        System.out.println(result);
    }
}

这个时候编译可以成功.

2.2 运行时通过

package com.bytedance;

class Plus implements IPlus{

    @Override
    public int plus(int a, int b) {
        return a + b;
    }
}

调用接口,就会执行回调方法.

package com.bytedance;

public class SonFactory extends FatherFactory {
    @Override
    public IPlus getPlusInstance() {
        return new Plus();
    }
}

子类继承FatherFactory并重写getPlusInstance()方法.因为之前方法的返回值是null,所以现在运行时要替换为真正的对象.

package com.bytedance;

class FatherFactory {
    private static FatherFactory sSonFactoryInstance;
    public static FatherFactory getSingleton() {
        if (sSonFactoryInstance == null){
            try {
                ClassLoader classLoader = FatherFactory.class.getClassLoader();
                sSonFactoryInstance = (FatherFactory)classLoader.loadClass("com.bytedance.SonFactory").newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return sSonFactoryInstance;
    }

    public IPlus getPlusInstance(){
        return null;
    }
}

我们把变量FatherFactory的引用名称从sFatherFactoryInstance修改为sSonFactoryInstance,主要是区分一件事情:编译时变量代表的是FatherFactory对象,运行时变量代表的是其子类对象SonFactory.

package com.bytedance;

public class Test {

    public static void main(String[] args) {
        FatherFactory sonFactory = FatherFactory.getSingleton();
        int result = sonFactory.getPlusInstance().plus(1,2);
        System.out.println(result);
    }

}

也只是修改了下引用的名称而已.再看下结果.正确.说明加载没有问题.

/usr/lib/jvm/java-8-openjdk-amd64/bin/...
3

Process finished with exit code 0

3. 后续

如果大家喜欢这篇文章,欢迎点赞!
如果想看更多ClassLoader 方面的文章,欢迎关注!

上一篇 下一篇

猜你喜欢

热点阅读