newInstance参数详解以及反射的应用

通过反射创建新的类示例,有两种方式: 
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
     }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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,该方法不返回结果    
     }
}

转载自:http://blog.csdn.net/qq_30175203/article/details/49666695

               点击打开链接

如有侵权,请联系删文

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值