您的位置:首页 > 编程语言 > Java开发

Java Reflect 反射 .invoke 示例

2016-02-23 22:58 435 查看
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;

 }

 

}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息