作为javaSE的最后一篇,反射更多的是一种编程理念或者说优化,对前面的java多态的一种优化,简单但是需要理解一下
这篇文章写的很好:
大白话说Java反射:入门、使用、原理
1、反射的概念:
- 反射是相对于正射来说的,正射是先通过构造方法创建类的对象,然后使用类的各种属性和方法
- 而反射是什么时候想要用到这个类了,就通过类名把这个类加载进来,然后获得构造方法,获得属性和方法,更加地可持续
方法:
获得类.class
大部分应用的是第一种,指导类名(完整的,包名+类名)可以和config配置文件结合起来
下面写一个代码包括以下的反射用法:
- 通过类名获得类
- 通过无参构造获得对象,需要从class向下转型
- 指定有参构造函数 ,参数都是字节码
- 用这个有参构造对象
- 获得字段(私有private属性)
- 去除私有权限
- 修改字段
- 获得无参方法
- 获得有参方法
实例代码:
package reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Reflection {
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("reflection.Student");//1、通过类名获得类
Student s = (Student) clazz.newInstance();//2、通过无参构造获得对象,需要从class向下转型
Constructor con = clazz.getConstructor(String.class,int.class); //3、指定有参构造函数,参数都是字节码
//T newInstance(Object... initargs)
Student str1 = (Student) con.newInstance("吴彦祖",23); //4、用这个有参构造对象
//Field field = clazz.getField("name");//5、获得字段(共有public属性)
Field field = clazz.getDeclaredField("name");//5、获得字段(私有private属性)
field.setAccessible(true); //6、去除私有权限
field.set(str1, "PziAn"); //7、修改字段
System.out.println(str1); //输出:Student [name=PziAn, age=23]
//方法 getMethod(String name, 类<?>... parameterTypes)
Method method1 = clazz.getMethod("eat"); //8、获得无参方法
method1.invoke(str1); //输出:吃魷魚絲!
Method method2 = clazz.getMethod("eat",int.class); //9、获得有参方法
method2.invoke(str1,8); //输出:吃魷魚絲8次!
}
}
输出:
Student [name=PziAn, age=23]
吃魷魚絲
吃魷魚絲8次!
2、通过反射越过泛型检查:
泛型只是在编译阶段起作用,运行阶段会被擦除,所以我们在编译后拿到这个类的字节码,可以做一些事情,比如在ArrayList<Integer> 中放String类型的数
编译:将文件.java变成机器能识别的字节码.class
实例代码:
package reflection;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class ArrayListwithreflection {
public static void main(String[] args) throws Exception {
ArrayList<Integer> list = new ArrayList<>();
list.add(111);
list.add(222);
Class clazz = Class.forName("java.util.ArrayList");
// 获得add方法
Method method = clazz.getMethod("add", Object.class);// 注意这里是object
method.invoke(list, "南京是一座很美的城市!");
System.out.println(list);
}
}
输出:
[111, 222, 南京是一座很美的城市!]