繁体   English   中英

Java 类加载和反射

[英]Java Classloading and Reflection

我正在使用 urlclassloader 在运行时加载 jar 文件。 Jar 文件和类正在成功加载。 我有一个带有返回对象 X 的方法的类。使用对象 X,我必须在 X 上调用 Setter 方法。

如何在 X 上调用 setter 方法?

我通过调用该方法返回了对象 X。

X = my.invoke(inst, obj);
  1. 我是否需要通过在 X 类上调用newInstance()方法再次创建实例?
  2. 要调用 Object X 的方法,我是否必须每次都调用method.invoke() 假设 X 对象有 5 个方法,找到该方法并使用Method.invoke.调用该方法Method.invoke.

您的建议将非常有帮助。

   File f1 = new File("/home/egkadas/CR364/lib/xxx.jar");
   URL urls [] = new URL[1];
   urls[0] = f1.toURL(); 
    
   URLClassLoader urlClass = URLClassLoader.newInstance(urls);
   Class c1 = urlClass.loadClass("com.xxxx.example.poc.Container");
   Container  inst = (Container)c1.newInstance();
    
   if(inst == null){
        System.out.println("Object is null");
   }else{
     Method my = c1.getMethod("getAttribute",null);
      Object[] obj = new Object[0];
 com.XXXXX.example.poc.Container.Attributes att =(com.XXXXX.example.poc.Container.Attributes)my.invoke(inst, obj);
      System.out.println(att);

   

罐子里的代码:

public class Container {
    
    public String id;
    
    public Container(){
        
    }
    
    public Container(String id){
        this.id=id;
    }

    public void setId(String id){
        this.id=id;
    }
    public Attributes getAttribute(){
        return new Attributes("check","12lb","15lb",100);
    }
    
    public List<Attributes> getAttributes(){
        List<Attributes> ats = new ArrayList<Attributes>();
        
        return ats;
    }
    
    public static class Attributes {
        public String name;
        public String weight;
        public String height;
        public int capacity;
        
        public Attributes(String name,String weight,String height,int capacity){
            this.name=name;
            this.weight=weight;
            this.height=height;
            this.capacity=capacity;
        }
    
        public Attributes(){
            
        }
        public String toString(){
            return this.name+" "+this.weight+"  "+this.height+" "+this.capacity;
        }
        
        public void setName(String name){
            this.name=name;
        }
        public void setWeight(String weight){
            this.weight =weight;            
        }
        public void setHeight(String height){
            this.height=height;
        }
        
        public void setCapacity(int cap){
            this.capacity=cap;
        }
    }
}

我是否需要通过在 X 类上调用 newInstance() 方法再次创建实例?

不,根据您的解释,您已经有一个对象 X。您不需要创建任何类型的新对象。

要调用对象 X 的方法,我是否必须每次都调用 method.invoke()? 假设 X 对象有 5 个方法,找到该方法并使用 Method.invoke 调用该方法。

反射是运行时的事情。 您不知道要使用的声明(或静态)类型。 您基本上只使用Object接口/合同。 因此,您需要通过反射实用程序完成所有工作。 如果要调用对象的方法,则需要检索相应的Method对象并使用正确的参数调用其invoke(..)方法。

这取决于哪个类加载器定义了 X 类。 如果它是父类加载器,您可以简单地转换您的返回值:

X x = (X) my.invoke(inst, obj);

然后像任何其他 java 对象一样使用它。

如果 X 是由您的自定义类加载器定义的,它会变得更加复杂,因为 X 的定义对于父类加载器加载的类是不可见的。 因此,这些类不能在其源代码中引用 X 的方法和字段。 通常的解决方法是在自定义类加载器中由 X 实现的父类加载器中有一个接口(我们称之为 Y)。 由于方法是在 Y 中声明的,它们可以从父类加载器访问,即使调用它们执行类 X 中的实现。

如果您也不能这样做,您仍然可以使用反射来调用这些方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM