通过反射创建新的类示例,有两种方式: 
Class.newInstance() 
Constructor.newInstance() 


以下对两种调用方式给以比较说明: 
Class.newInstance() 只能够调用无参的构造函数,即默认的构造函数; 
Constructor.newInstance() 可以根据传入的参数,调用任意构造构造函数。 


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


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


Class A(被调用的示例): 
Java代码  

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(调用者): 
Java代码  

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()。


Java中要用到反射,首先就必须要获取到对应的class对象,在Java中有三种方法获取类对应的class对象。

1、通过类的.class属性

2、通过类实例的getClass()方法获取

3、通过Class.forName(String className)方法获取

现在比如在package下有个类Calculator


    
public  class  Calculator{ 
     
     public  double  add( double  score1, double  score2){
         return  score1 + score2;
     }
     
     public  void  print(){
         System.out.println( "OK" );
     }
     
     public  static  double  mul( double  score1, double  score2){
         return  score1 * score2;
     }
}

public  class  CalculatorTest {
 
     public  static  void  main(String[] args)  throws  Exception {
         //通过类的.class属性获取
         Class<Calculator> clz = Calculator. class ;
         //或者通过类的完整路径获取,这个方法由于不能确定传入的路径是否正确,这个方法会抛ClassNotFoundException
//      Class<Calculator> clz = Class.forName("test.Calculator");
         //或者new一个实例,然后通过实例的getClass()方法获取
//      Calculator s = new Calculator();
//      Class<Calculator> clz = s.getClass();
         //1. 获取类中带有方法签名的mul方法,getMethod第一个参数为方法名,第二个参数为mul的参数类型数组
         Method method = clz.getMethod( "mul" ,  new  Class[]{ double . class , double . class });
         //invoke 方法的第一个参数是被调用的对象,这里是静态方法故为null,第二个参数为给将被调用的方法传入的参数
         Object result = method.invoke( null ,  new  Object[]{ 2.0 , 2.5 });
         //如果方法mul是私有的private方法,按照上面的方法去调用则会产生异常NoSuchMethodException,这时必须改变其访问属性
         //method.setAccessible(true);//私有的方法通过发射可以修改其访问权限
         System.out.println(result); //结果为5.0
         //2. 获取类中的非静态方法
         Method method_2 = clz.getMethod( "add" ,  new  Class[]{ double . class , double . class });
         //这是实例方法必须在一个对象上执行
         Object result_2 = method_2.invoke( new  Calculator(),  new  Object[]{ 2.0 , 2.5 });
         System.out.println(result_2); //4.5
         //3. 获取没有方法签名的方法print
         Method method_3 = clz.getMethod( "print" ,  new  Class[]{});
         Object result_3 = method_3.invoke( new  Calculator(),  null ); //result_3为null,该方法不返回结果    
     }
}

如有侵权,请联系删文