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;
}
}