栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

用不同的包名称动态加载java中的类

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

用不同的包名称动态加载java中的类

如Pete所述,可以使用ASM字节码库来完成此操作。实际上,该库实际上带有一个专门用于处理这些类名重新映射(

RemappingClassAdapter
)的类。这是使用此类的类加载器的示例:

public class MagicClassLoader extends ClassLoader {    private final String defaultPackageName;    public MagicClassLoader(String defaultPackageName) {        super();        this.defaultPackageName = defaultPackageName;    }    public MagicClassLoader(String defaultPackageName, ClassLoader parent) {        super(parent);        this.defaultPackageName = defaultPackageName;    }    @Override    public Class<?> loadClass(String name) throws ClassNotFoundException {        byte[] bytepre = ...; // I will leave this part up to you        byte[] remappedBytepre;        try { remappedBytepre = rewriteDefaultPackageClassNames(bytepre);        } catch (IOException e) { throw new RuntimeException("Could not rewrite class " + name);        }        return defineClass(name, remappedBytepre, 0, remappedBytepre.length);    }    public byte[] rewriteDefaultPackageClassNames(byte[] bytepre) throws IOException {        ClassReader classReader = new ClassReader(bytepre);        ClassWriter classWriter = new ClassWriter(classReader, 0);        Remapper remapper = new DefaultPackageClassNameRemapper();        classReader.accept(     new RemappingClassAdapter(classWriter, remapper),     0 );        return classWriter.toByteArray();    }    class DefaultPackageClassNameRemapper extends Remapper {        @Override        public String map(String typeName) { boolean hasPackageName = typeName.indexOf('.') != -1; if (hasPackageName) {     return typeName; } else {     return defaultPackageName + "." + typeName; }        }    }}

为了说明这一点,我创建了两个类,它们都属于默认包:

public class Customer {}

public class Order {    private Customer customer;    public Order(Customer customer) {        this.customer = customer;    }    public Customer getCustomer() {        return customer;    }    public void setCustomer(Customer customer) {        this.customer = customer;    }}

这是任何重新映射

Order
之前 的清单:

> javap -private -c命令从“ Order.java”编译公共类Order扩展java.lang.Object {私人客户客户;公共秩序(客户);  码:   0:加载_0   1:调用特殊#10; //方法java / lang / Object。“” :()V   4:aload_0   5:aload_1   6:普特菲尔德#13;//字段客户:LCustomer;   9:返回公共客户getCustomer();  码:   0:加载_0   1:getfield#13;//字段客户:LCustomer;   4:阿伦public void setCustomer(Customer);  码:   0:加载_0   1:aload_1   2:putfield#13;//字段客户:LCustomer;   5:返回}

这是重新映射

Order
的列表(
com.mycompany
用作默认软件包):

> javap -private -c命令从“ Order.java”编译公共类com.mycompany.Order扩展了com.mycompany.java.lang.Object {私人com.mycompany.Customer客户;公共com.mycompany.Order(com.mycompany.Customer);  码:   0:加载_0   1:调用特殊#30; //方法“ com.mycompany.java/lang/Object"."":()V   4:aload_0   5:aload_1   6:普特菲尔德#32;//字段客户:Lcom.mycompany.Customer;   9:返回公共com.mycompany.Customer getCustomer();  码:   0:加载_0   1:getfield#32;//字段客户:Lcom.mycompany.Customer;   4:阿伦公共无效setCustomer(com.mycompany.Customer);  码:   0:加载_0   1:aload_1   2:putfield#32;//字段客户:Lcom.mycompany.Customer;   5:返回}

如您所见,重新映射更改了

Order
对的所有引用
com.mycompany.Order
和对的所有
Customer
引用
com.mycompany.Customer

该类加载器将必须加载以下任一类的所有类:

  • 属于默认软件包,或
  • 使用属于默认软件包的其他类。


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/414123.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号