通过反射创建新类示例的两种方式及比较

  |   0 评论   |   1,017 浏览

From Evernote:

通过反射创建新类示例的两种方式及比较

通过反射创建新类示例的两种方式及比较

作者BLOG:http://blog.csdn.net/fenglibing

通过反射创建新的类示例,有两种方式:

Class.newInstance()

Constructor.newInstance()



以下对两种调用方式给以比较说明:

l             Class.newInstance() 只能够调用无参的构造函数,即默认的构造函数;而Constructor.newInstance() 可以根据传入的参数,调用任意构造构造函数。

l             Class.newInstance() 抛出所有由被调用构造函数抛出的异常。

l             Class.newInstance() 要求被调用的构造函数是可见的,也即必须是public类型的; Constructor.newInstance() 在特定的情况下,可以调用私有的构造函数。



Class A(被调用的示例):

view plaincopy to clipboardprint?
public class A {  
    private A(){  
        System.out.println("A's constructor is called.");  
    }  
    private A(int a,int b){  
        System.out.println("a:"+a+" b:"+b);  
    }  

public class A {
    private A(){
        System.out.println("A's constructor is called.");
    }
    private A(int a,int b){
        System.out.println("a:"+a+" b:"+b);
    }
}



Class B(调用者):

view plaincopy to clipboardprint?
import java.lang.reflect.Constructor;  
 
import static java.lang.System.out;  
 
public class B {  
 
    public static void main(String[] args) {  
 
        B b=new B();  
 
        out.println("通过Class.NewInstance()调用私有构造函数:");  
 
        b.newInstanceByClassNewInstance();  
 
        out.println("通过Constructor.newInstance()调用私有构造函数:");  
 
        b.newInstanceByConstructorNewInstance();  
 
    }  
 
    /*通过Class.NewInstance()创建新的类示例*/ 
 
    private void newInstanceByClassNewInstance(){  
 
        try {  
 
            /*当前包名为reflect,必须使用全路径*/ 
 
            A a=(A)Class.forName("reflect.A").newInstance();  
 
        } catch (Exception e) {  
 
            out.println("通过Class.NewInstance()调用私有构造函数【失败】");  
 
        }  
 
    }  
 
    /*通过Constructor.newInstance()创建新的类示例*/ 
 
    private void newInstanceByConstructorNewInstance(){  
 
        try {  
 
                      /*可以使用相对路径,同一个包中可以不用带包路径*/ 
 
            Class c=Class.forName("A");  
 
            /*以下调用无参的、私有构造函数*/ 
 
            Constructor c0=c.getDeclaredConstructor();  
 
            c0.setAccessible(true);  
 
            A a0=(A)c0.newInstance();  
 
              
 
            /*以下调用带参的、私有构造函数*/ 
 
            Constructor c1=c.getDeclaredConstructor(new Class[]{int.class,int.class});  
 
            c1.setAccessible(true);  
 
            A a1=(A)c1.newInstance(new Object[]{5,6});  
 
        } catch (Exception e) {  
 
            e.printStackTrace();  
 
        }         
 
    }  
 

import java.lang.reflect.Constructor;

import static java.lang.System.out;

public class B {

    public static void main(String[] args) {

        B b=new B();

        out.println("通过Class.NewInstance()调用私有构造函数:");

        b.newInstanceByClassNewInstance();

        out.println("通过Constructor.newInstance()调用私有构造函数:");

        b.newInstanceByConstructorNewInstance();

    }

    /*通过Class.NewInstance()创建新的类示例*/

    private void newInstanceByClassNewInstance(){

        try {

            /*当前包名为reflect,必须使用全路径*/

            A a=(A)Class.forName("reflect.A").newInstance();

        } catch (Exception e) {

            out.println("通过Class.NewInstance()调用私有构造函数【失败】");

        }

    }

    /*通过Constructor.newInstance()创建新的类示例*/

    private void newInstanceByConstructorNewInstance(){

        try {

                      /*可以使用相对路径,同一个包中可以不用带包路径*/

            Class c=Class.forName("A");

            /*以下调用无参的、私有构造函数*/

            Constructor c0=c.getDeclaredConstructor();

            c0.setAccessible(true);

            A a0=(A)c0.newInstance();

           

            /*以下调用带参的、私有构造函数*/

            Constructor c1=c.getDeclaredConstructor(new Class[]{int.class,int.class});

            c1.setAccessible(true);

            A a1=(A)c1.newInstance(new Object[]{5,6});

        } catch (Exception e) {

            e.printStackTrace();

        }      

    }

}
 

输入结果如下:

通过Class.NewInstance()调用私有构造函数:

通过Class.NewInstance()调用私有构造函数【失败】

通过Constructor.newInstance()调用私有构造函数:

A's constructor is called.

a:5 b:6


说明方法newInstanceByClassNewInstance调用失败,而方法newInstanceByConstructorNewInstance则调用成功。如果被调用的类的构造函数为默认的构造函数,采用Class.newInstance()则是比较好的选择,一句代码就OK;如果是老百姓调用被调用的类带参构造函数、私有构造函数,就需要采用Constractor.newInstance(),两种情况视使用情况而定。不过Java Totorial中推荐采用Constractor.newInstance()。

评论

发表评论

validate