import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.junit.Test;
public class ReflectOperateObj {
/*
* 理一下 传统方式: User u=new User();
*
* 类反射的方式 Class c=Class.forName("cn.hncu...User");//1 Class paramTypes[]=
* {String.class,int.class}; Constructor con = c.getConstructor(paramTypes);
* //2 Object params[] = {"Jack",25}; Object u=con.newInstance(params); //3
*
*
* Class c = Class.forName("cn.hncu...User"); //1Constructor con =
* c.getConstructor( new Class[]{String.class,int.class} ); //2Object u =
* con.newInstance( new Object[]{"Jack",25} ); //3
*/
// 构造器的操作(调用)
@Test
public void operateConstructor() throws Exception {
Class<?> c = Class.forName("cn.hncu.reflect.fetch.User");
// 1 该方式只能调用空参构造器
Object obj = c.newInstance();
System.out.println(obj);
// 2 调用指定的构造器如: public User(String name, int age)
// ///2.1先获取指定的构造器///
/*
* //形参是可变参数,传实参时可以是若干个实参 Class c1=String.class; Class c2=int.class;
* Constructor con = c.getDeclaredConstructor(c1,c2);
* System.out.println(con);
*/
// 形参是可变参数,传实参时也可以是一个实参数组
/*
* Class paramTypes[] = new Class[2]; paramTypes[0] = String.class;
* paramTypes[1] = int.class; Constructor con =
* c.getDeclaredConstructor(paramTypes); //关键点1
*/
Constructor<?> con = c.getDeclaredConstructor(new Class[] {
String.class, int.class });
// System.out.println(con);
// //2.2 调用指定的构造器对象con/// new User("Jack",22);
Object params[] = new Object[2];
params[0] = "Jack";
params[1] = 22;
Object obj2 = con.newInstance(params);
System.out.println(obj2);
}
// 方法的操作(调用)
@Test
public void operateMethod() throws Exception {
// 1加载类模板(获得class对象)
Class<?> c = Class.forName("cn.hncu.reflect.fetch.User");
// 调用方法
// ※2.1调用"空参"方法,如toString() ---User u = new User(); u.toString()
// 1)先获取指定方法
Method m1 = c.getDeclaredMethod("toString", null);
// 2)再调用
// Object u = c.newInstance();
Object u = new User("张三", 20);
Object returnValue = m1.invoke(u, null); // u.toString();
System.out.println(returnValue);
// ※2.2调用"有参"方法, 如:public double sum(int a, double b) ----returnValue =
// u.sum(100,55.6)
// 1)先获取指定方法
Class<?> parameterTypes[] = new Class[2];
// parameterTypes[0] = int.class;//AC
// parameterTypes[0] = Integer.class;//WA ---类反射中的方法参数匹配没有装箱拆箱
parameterTypes[0] = Integer.TYPE;// AC ---包装类的TYPE属性就是对应的基本数据类型
parameterTypes[1] = double.class;
// parameterTypes[1] = Double.class;//WA
// parameterTypes[1] = Double.TYPE;//AC
Method m2 = c.getDeclaredMethod("sum", parameterTypes);// 关键点1
// 2)再调用
Object u2 = c.newInstance();
Object args[] = { 100, 55.6 };
Object returnValue2 = m2.invoke(u2, args); // 关键点2 returnValue =
// u2.sum(100,55.6)
System.out.println("returnValue2: " + returnValue2);
// ※2.3调用静态方法, 如:final static void aa()
// 1)先获取指定方法 (私有方法必须通过Declared方式获取)
Method m3 = c.getDeclaredMethod("aa", null);
// 2)再调用
Object returnValue3 = m3.invoke(null, null);
System.out.println("returnValue3: " + returnValue3);
}
// 演练一下,用类反射构造并封装一个User对象
@Test
public void operateConstructorMethod() throws Exception {
// 加载类模板
Class<?> c = Class.forName("cn.hncu.reflect.fetch.Person");
// 调用构造器
Class<?> parameterTypes[] = { String.class, int.class };
Constructor<?> con = c.getConstructor(parameterTypes);
Object obj = con.newInstance("王五", 30); // obj = new User("王五",30)
Method m = c.getMethod("setId", String.class);
m.invoke(obj, "U001"); // obj.setId("U001");
System.out.println(obj);
}
// 属性的操作(调用)
@Test
public void operateField() throws Exception {
// 1加载类模板(获得class对象)
Class<?> c = Class.forName("cn.hncu.reflect.fetch.User");
// 2获取指定的属性
Field fld = c.getField("a");
// 3操作该属性 //读取属性值 User u = new User(); u.a
Object u = c.newInstance();
// fld.set(u, 200); //设置属性值
// fld.setDouble(u, 123);//WA:方法与fld属性 类型不匹配
fld.setInt(u, 12);
// 读取属性值
Object value = fld.get(u); // 方式1: 通用,但获取的属性值类型比较模糊(Object)
int value2 = fld.getInt(u); // 方式2:专用,获取的属性值类型精确,类似函数还有:getBoolean(obj),getChar(obj),需要和fld对应的类型匹配
System.out.println(value + "," + value2);
}
//暴力访问----该问非公开权限的构造器、方法或属性
@Test
public void accessViolence() throws Exception{
Class<?> c = Class.forName("cn.hncu.reflect.fetch.User");
Field fld = c.getDeclaredField("id");
Object obj = new User(); //Object obj = c.newInstance();
fld.setAccessible(true); //打开暴力访问开关,注:该方法是AccessibleObject类中的方法,该类是Field、Method和Constructor的公共父类,因此都可以调用以进行暴力访问。
fld.set(obj, "U007");
System.out.println(obj);
}
}
java 类反射3
最新推荐文章于 2021-08-12 12:06:30 发布