十三、反射
获取类对象
获取类对象的3种方式:
public class Txt {
public static void main(String[] args) throws ClassNotFoundException {
Class c1 = Class.forName("Person");
Class c2 = Person.class;
Class c3 = new Person("m").getClass();
System.out.println(c1.hashCode());
System.out.println(c2.hashCode());
System.out.println(c3.hashCode());
}
}
无论什么途径获取类对象,都会导致静态属性被初始化,而且只会执行一次。(除了直接使用 Class c = Hero.class 这种方式,这种方式不会导致静态属性被初始化)
创建对象(利用反射)
import java.lang.reflect.Constructor;
public class Txt {
public static void main(String[] args) {
try {
//得到类对象
Class c1 = Class.forName("Person");
//由类对象获取构造方法
Constructor constructor = c1.getConstructor(String.class,int.class,int.class);
//由构造方法实例化对象
Person p = (Person) constructor.newInstance("姓名",12,5000);
System.out.println(p);
} catch (Exception e) {
e.printStackTrace();
}
}
}
访问属性(利用反射)
import java.lang.reflect.Field;
public class Txt {
public static void main(String[] args) {
//对于private修饰的成员,需要使用setAccessible(true)才能访问和修改
Person p1 = new Person("张三");
try {
//得到类对象
Class c1 = p1.getClass();
//获取person变量名字为name的字段
Field f = c1.getDeclaredField("name");
f.set(p1,"王五");
System.out.println(p1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
getField 只能获取public的,包括从父类继承来的字段。
getDeclaredField 可以获取本类所有的字段,包括private的,但是不能获取继承来的字段。 (注: 这里只能获取到private的字段,但并不能访问该private字段的值,除非加上setAccessible(true))
调用方法(利用反射)
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Txt {
public static void main(String[] args) {
//对于private修饰的成员,需要使用setAccessible(true)才能访问和修改
Person p1 = new Person("张三");
try {
//得到类对象
Class c1 = p1.getClass();
//获取方法名为income,变量类型为int的方法。
Method m = c1.getDeclaredMethod("income",int.class);
m.invoke(p1,100);
} catch (Exception e) {
e.printStackTrace();
}
}
}