<反射>
1.Class
.class文件加载到内存中就是一个Class对象
获取Class对象的方式有3种:
Class.forName();
类名.class
对象.getClass()
例如:
-
public class Demo1_Reflect {
-
-
-
-
-
-
public static void main(String[] args) throws ClassNotFoundException {
-
Class<?> clazz1 = Class.forName("cn.itcast.bean.Person");
-
Class<?> clazz2 = Person.class;
-
-
Person p = new Person();
-
Class<?> clazz3 = p.getClass();
-
-
System.out.println(clazz1 == clazz2);
-
System.out.println(clazz2 == clazz3);
-
}
-
-
}
-
public class Demo2_Reflect {
-
-
-
-
-
-
-
-
-
public static void main(String[] args) throws Exception {
-
BufferedReader br = new BufferedReader(new FileReader("config.txt"));
-
Class<?> clazz = Class.forName(br.readLine());
-
Fruit f = (Fruit) clazz.newInstance();
-
Juicer j = new Juicer();
-
j.run(f);
-
}
-
-
}
-
interface Fruit {
-
public void squeeze();
-
}
-
-
class Apple implements Fruit {
-
public void squeeze() {
-
System.out.println("榨出一杯苹果汁儿");
-
}
-
}
-
-
class Orange implements Fruit {
-
public void squeeze() {
-
System.out.println("榨出一杯桔子汁儿");
-
}
-
}
-
-
class Juicer {
-
public void run(Fruit f) {
-
f.squeeze();
-
}
-
}
2.Constructor
Class类的newInstance()方法是使用该类无参的构造函数创建对象
调用Class类的getConstructor(String.class,int.class)方法获取一个指定的构造函数,然后再调用Constructor类的newInstance("张三",20)方法创建对象
-
public class Demo3_Constructor {
-
public static void main(String[] args) throws Exception {
-
Class<?> clazz = Class.forName("cn.itcast.bean.Person");
-
Person p = (Person) clazz.newInstance();
-
System.out.println(p);
-
Constructor con = clazz.getConstructor(String.class,int.class);
-
Person p = (Person) con.newInstance("张三",23);
-
System.out.println(p);
-
}
-
-
}
3.Field
Class.getField(String)方法可以获取类中的指定字段(可见的), 如果是私有的可以用getDeclaedField("name")方法获取
通过set(obj, "李四")方法可以设置指定对象上该字段的值, 如果是私有的需要先调用setAccessible(true)设置访问权限
用获取的指定的字段调用get(obj)可以获取指定对象中该字段的值
-
public class Demo4_Field {
-
public static void main(String[] args) throws Exception {
-
Class<?> clazz = Class.forName("cn.itcast.bean.Person");
-
Constructor con = clazz.getConstructor(String.class,int.class);
-
Person p = (Person) con.newInstance("张三",23);
-
-
-
-
Field f = clazz.getDeclaredField("name");
-
f.setAccessible(true);
-
f.set(p, "李四");
-
System.out.println(p);
-
}
-
-
}
4.Method
Class.getMethod(String, Class...) 和 Class.getDeclaredMethod(String, Class...)方法可以获取类中的指定方法
调用invoke(Object, Object...)可以调用该方法
Class.getMethod("eat") invoke(obj) Class.getMethod("eat",int.class) invoke(obj,10)
-
public class Demo5_Method {
-
public static void main(String[] args) throws Exception {
-
Class<?> clazz = Class.forName("cn.itcast.bean.Person");
-
Constructor con = clazz.getConstructor(String.class,int.class);
-
Person p = (Person) con.newInstance("张三",23);
-
-
Method m = clazz.getMethod("eat");
-
m.invoke(p);
-
-
Method m2 = clazz.getMethod("eat", int.class);
-
m2.invoke(p, 10);
-
}
-
-
}
5.泛型反射
创建一个集合对象,泛型为String类型,需要向这个集合中添加Integer对象
泛型在编译时存在,运行时会被擦除
-
public class Test3 {
-
-
public static void main(String[] args) throws Exception {
-
ArrayList<String> list = new ArrayList<>();
-
list.add("黑");
-
list.add("马");
-
list.add("程");
-
list.add("员");
-
-
Class<?> clazz = Class.forName("java.util.ArrayList");
-
Method m = clazz.getMethod("add", Object.class);
-
m.invoke(list, 521);
-
m.invoke(list, true);
-
System.out.println(list);
-
-
}
-
-
}