------<a href="http://www.itheima.com"
target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
<反射>
1.Class
.class文件加载到内存中就是一个Class对象
获取Class对象的方式有3种:
Class.forName();
类名.class
对象.getClass()
例如:
[java] view
plaincopy
- public class Demo1_Reflect {
- /**
- * @param args
- * @throws ClassNotFoundException
- */
- 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); //true
- System.out.println(clazz2 == clazz3); //true
- }
- }
[java] view
plaincopy
- public class Demo2_Reflect {
- /**
- * @param args
- * 榨汁机(Juicer)榨汁的案例
- * 分别有水果(Fruit)苹果(Apple)香蕉(Banana)桔子(Orange)榨汁(squeeze)
- * @throws IOException
- * @throws Exception
- */
- public static void main(String[] args) throws Exception {
- BufferedReader br = new BufferedReader(new FileReader("config.txt"));//创建流对象关联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)方法创建对象
[java] view
plaincopy
- 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);
[java] view
plaincopy
- 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)可以获取指定对象中该字段的值
[java] view
plaincopy
- 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.getField("name");
- System.out.println(f);*/
- 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)
[java] view
plaincopy
- 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对象
泛型在编译时存在,运行时会被擦除
[java] view
plaincopy
- 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);
- }
- }