Java Reflect 反射 .invoke 示例

package com.age.www;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.lang.reflect.AccessibleObject;
public class ReflectionDemo1 {

 public static void main(String[] args) throws Exception {
  //测试的时候throws Exception就可以了,下面省却了很多try catch麻烦。
  Emploree2 emp=new Emploree2();
  Emploree2 emp2=new Emploree2("zhangsan",30);
  try {
//   System.out.println(Class.forName("com.age.www.Emploree2"));
   Constructor con=Class.forName("com.age.www.Emploree2").getDeclaredConstructor(String.class,Integer.TYPE);
   //这里已经标明了是(String,int)类型的构造函数了。下面构造函数调用newInstance的时候必须加上对应的参数:
   System.out.println(con);
   Emploree2 emp3=(Emploree2)con.newInstance("甲乙",32);
   emp3.tell();
   //以上为调用带参构造函数。
   
   //无参构造函数构建对象并调用方法。
   Constructor con2=Class.forName("com.age.www.Emploree2").getDeclaredConstructor(null);
   Emploree2 emp4=(Emploree2)con2.newInstance();  //con2.newInstance返回的是Object类型的对象,必须要强制转型对应的想用的引用类对象。
   //Type mismatch: cannot convert from Object to Emploree2  如果不强制转型报错。
     /*
    //newInstance(Objec...args)这里本来就是不确定个数的Object对象,如果没有也行。直接newInstance.多个的话逗号隔开。也可以使用new Object[]{"aa",20,boolean};建立一个Object数组。
   //以getDeclaredMethod方法为例,parameterTypes英文里面指定的是参数数组。由于参数是数组,在执行时,会被拆分成为基础类型对象,或者引用对象。 也就是说也可以直接
   //用,逗号隔开这几个参数值,不用Class或者Object数组。 如果参数长度为0时,可以使用null代表0个参数。
   //public Method getDeclaredMethod(String name,
    //  Class<?>... parameterTypes)
   //parameterTypes - the parameter array     
    * */
   emp4.tell();
   emp4.tell("李二", 24);
   //emp4.getObj();  The method getObj() from the type Emploree2 is not visible  如果直接调用这个对象的私有方法private方法 也不行,需要将这个私有方法设定为public。
   
   //Method mtd=Class.forName("Emploree2").getDeclaredMethod("getObj",null);  //直接null还是提示不准确,这种情况还是使用new Class[]{};
   
   System.out.println("mtd setAccessible方法检测;");
   Method mtd=Class.forName("com.age.www.Emploree2").getDeclaredMethod("getObj",new Class[]{});
   mtd.setAccessible(true);  //如果不将private属性的方法设定为true,则下面方法不能调用。 //Constructor不能将private改为public。
   String str=(String)mtd.invoke(emp4, new Object[]{});  //Method对象调用实例对象的方法法时,返回值都是Object。  API上面写的是“T”泛型。 默认就是Object类型,需要向下转型为String。
   System.out.println(str);
   
   
   System.out.println("**********************Filed对象");
   
   Field fld=Class.forName("com.age.www.Emploree2").getDeclaredField("name");
   fld.setAccessible(true);//由于name也是私有属性也必须设定权限才能进行修改值。。。。
   fld.set(emp2, "zhangsan ZS ZS");
   //emp2.tell();  修改后就可以直接调用原来的对象,执行方法。 A45
   String strname=(String)fld.get(emp2);
   System.out.println(strname);
   Method mtd2=Class.forName("com.age.www.Emploree2").getDeclaredMethod("tell",null);
   //emp2.getObj();The method getObj() from the type Emploree2 is not visible;
   
   mtd2.invoke(emp2,null);//可以看到输出结果,上面已经对对象进行了修改。 也可以通过method对象invoke特定对象的方法 反射执行 和A45两种调用方式。
   
   
   
   
   
   
   
   Method[] mary=Class.forName("com.age.www.Emploree2").getMethods();
   for(int i=0;i<mary.length;i++){
    System.out.println(mary[i].getName()+"--"+mary[i].getModifiers()+"--"+mary[i].getReturnType());
   }
   System.out.println("**********************************************setAccessible之前");
   Method[] mary2=mary;
   AccessibleObject.setAccessible(mary2,true);  //对一组accessibleObject对象设定更改访问权限,改为true或者false。。。public protected,default,or private属性更改。
   for(int i=0;i<mary2.length;i++){
    System.out.println(mary2[i].getName()+"--"+mary2[i].getModifiers()+"--"+mary2[i].getReturnType());
   }
   
   
   
   
   
   Class.forName("com.age.www.Emploree2").getDeclaredMethod("tell", String.class,int.class).invoke(emp2,"zhouliu",34);
   //这里调用当前类所声明的方法,里面getMethod(String name,Class<?>... parameterTypes):Class...parameterType 后面的参数不用是数组,因为不确定参数的个数。数组就确定了参数个数。 直接逗号隔开就行了。
   //如果 参数个数为0个,则使用null,或者new Object[]{} 数组。调用的时候,Object[]数组会自动解开,然后里面的对象会作为参数。 如果这个数组为0就是new Object[]{}。无参类型。
   // .invoke方法也一样,调用当前类生命的对象,然后加上参数,这个参数也是用逗号隔开就可以了。 这里调用的时候就可以改参数的值。体现出反射对方法调用的修改……
   

   
  } catch (ClassNotFoundException e) {
   e.printStackTrace();
  } catch (NoSuchMethodException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (SecurityException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IllegalArgumentException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (InstantiationException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
}
}

class Emploree2 {
 private String name="zhangsan";
 private int age=20;
 Emploree2(){System.out.println("无参构造方法");}
 Emploree2(String name,int age){
  this.name=name;
  this.age=age;
 }
 
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
 
 
 public void tell(String name,int age){
  
  System.out.println(name+age);
 }
 public void tell(){
  
  System.out.println(name+age);
 }
 private String getObj(){
  return "name+age:"+name+age;
 }
 
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值