Java类加载和反射

时间:2014-02-28 21:34:34

标签: java classloader

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

如何在X上调用setter方法?

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

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

    您的建议非常有用。

       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);
    

    jar中的代码:

    公共类容器{

    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;
        }
    }
    

    }

2 个答案:

答案 0 :(得分:1)

  

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

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

  

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

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

答案 1 :(得分:0)

这取决于哪个类加载器定义了X类。如果它是父类加载器,您只需转换返回值:

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

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

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

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