public class Person {
private String name;
private int age;
public static final double PI=3.14;
public double value;
public Person() {
name="匿名";
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
private Person(String name) {
this.name = name;
}
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;
}
@Override
public String toString() {
System.out.println("111111111");
return name + ", " + age;
}
public int sum( int m, int n){
int s=0;
for(int i=m;i<=n;i++){
s +=i;
}
return s;
}
public static void aa(){
System.out.println(PI);
}
private int sum(int n){
return n+100;
}
}
public class ReflectOperateObj {
private static final String className=”cn.hncu.reflect.Person”;
使用构造器新建对象
最核心的代码: Constructor con= c.getConstructor(paramTypes); con.newInstance(args);
@Test
public void operateConstructor(){
try {
Class c = Class.forName(className);
1 .调用空参构造方法
//简便方式new一个空参对象
Object obj = c.newInstance();//选用空参构造方法新建一个对象
System.out.println(obj);
//常规方式:先拿到对应构造器的对象,然后利用该构造器对象(代表那个构造函数)调用newInstance()方法造出对象
Constructor con = c.getConstructor(null);//获取空参构造方法
Object obj2 = con.newInstance(null);
System.out.println(obj2);
2 .调用非空参构造方法
//只能常规方法:必须先通过形参获得对应的构造方法,然后通过实参调用该构造方法
//2.1获取指定的构造器--通过形参
Class parameterTypes[] = new Class[2];
parameterTypes[0] = String.class;
parameterTypes[1] = Integer.TYPE;
Constructor con2= c.getConstructor(parameterTypes);
//2.2调用该构造器来new对象---通过实参
Object params[] = new Object[2];//调用构造方法是要传入的参数
params[0]=new String("Jack");
params[1]=new Integer(24);
Object obj3 = con2.newInstance(params);
System.out.println(obj3);
} catch (Exception e) {
e.printStackTrace();
}
}
调用普通方法
最核心的代码: Method m = c.getMethod(name,paramTypes); m.invoke(obj,args);**
@Test
public void callMethod(){
try {
Class c = Class.forName(className);
1 .调用空参方法
Person p = new Person(); p.toString();
//1.1先获得该Method对象---通过形参
Method m = c.getMethod("toString", null);
//1.2再让该Method对象执行---通过实参
Object p = c.newInstance();
Object returnValue = m.invoke(p, null);//执行方法---p.toString()
System.out.println(">>>> "+ returnValue);
2.调用非空参方法
//2.1先获得该Method对象---通过形参
Class parameterTypes[] = new Class[2];
parameterTypes[0] = int.class;//参数类型为int--OK
//parameterTypes[0] = Integer.TYPE;//参数类型为int--OK
//下句小细节:因为这是一个纯粹的类,里面没有拆箱功能,无法当作int类型。但如果sum()中的第一个参数就是Integer类型,那么下句OK
//parameterTypes[0] = Integer.class;//参数类型为int--ERROR
parameterTypes[1] = int.class;
Method m2 = c.getDeclaredMethod("sum", parameterTypes);
//2.2再让该Method对象执行---通过实参 p.sum(100,200);
Object p2 = c.newInstance();
Object args[] = new Object[2];
args[0] = 1;
args[1] =100;
Object res = m2.invoke(p2, args);
System.out.println("res: " + res);
3.调用静态方法
Method m3 = c.getMethod("aa", null);
m3.invoke(null, null);//静态方法的调用不需要对象,类名可以省略,所以传入null就行。至于方法的实参,同前
} catch (Exception e) {
e.printStackTrace();
}
}
访问属性(成员变量、类变量)
—-最核心代码: Field fld = c.getFild(name); 专用setter-getter方法:fld.setDouble(p,value);fld.getDouble(p) 通用setter-getter方法:fld.set(p,value);fld.get(p)
//Person p = new Person(); p.value=11.22;**
@Test
public void AccessField(){
try {
Class c = Class.forName(className);
//获取Field对象
Field fld = c.getField("value");
//操纵该Field对象,以进行读写属性值
Object p = c.newInstance();
//通用的setter-getter方法
//fld.set(p,11.22);//设置值
//double x = (Double)fld.get(p) + 100;//获取值
//专用的setter-getter方法
fld.setDouble(p, 22.33);
double x = fld.getDouble(p) + 100;//获取值
System.out.println(x);
} catch (Exception e) {
e.printStackTrace();
}
}
暴力访问
**---访问类中的私有成员(构造器、普通方法、属性)---这三者的公共父类AccessibleObject中的方法setAccessible(boolean flag)可以打开私有访问权限**
//强行访问私有方法: private int sum(int n)
@Test
public void AccessBlood(){
try {
Class c = Class.forName(className);
Method m = c.getDeclaredMethod("sum", int.class);
m.setAccessible(true);//暴力访问,打开访问权限。---其实是调用父类AccessibleObject中的该方法
Object res = m.invoke(c.newInstance(), 100);
System.out.println(res);
} catch (Exception e) {
e.printStackTrace();
}
}
}