近期在看Netty相关的学习资料,其中涉及到了手写框架的部分,有用到Java反射这一部分的知识,于是整理学习一番。
反射是框架设计的灵魂。
Java反射的定义
java反射是指在运行状态中,
对于任意一个类,都能知道这个类的所有属性和方法。
对于任意一个对象,都能调用它的任意一个方法和属性。
这种动态获取信息以及动态调用方法的功能称为 Java的反射机制。
为什么要用反射
为什么要用反射呢?直接new一个对象不是很方便吗?
反射的初衷,并不是为了让你更方便的创建对象,而是让你在写代码时更加灵活,降低耦合度,提高代码的自适应能力。
例: 创建一千个名字不一样的对象。需要写new代码一千行吗,引入一千个类?通过反射则不用引入一千个类。
获取Class对象
class对象是Java反射机制实现的基础。
获取class对象有以下几种方法:
-
通过Class.forName(“类路径‘)加载类 ------ 常用
Class<?> cls = Class.forName("com.jishucai.reflection.Student");//forName(包名.类名) Student s1 = (Student)cls.newInstance(); -
通过new的对象的
.getClass()方法Student s2 = new Student(); Class stuClass = s2.getClass(); -
通过类.class文件
Student s3 = Student.class;
获取类的信息
前面已经说过,可以通过反射获取到类的各种信息,下面一 一说明。
获取类的构造函数
-
单独获取某个构造函数
getDeclaredConstructor(顺序传入参数类型)----不分构造器类型,public|!public getConstructor(参数类型)---只获取public类型 eg: getDeclaredConstructor(String.class) getConstructor(String.class) -
获取类的所有构造函数
getDeclaredConstructors() --- 获取所有的构造器 getConstructors() --- 获取public的构造器
获取类的成员方法
-
获取单个类的成员方法
getDeclaredMethod(name, class[]) --- 获取指定参数的成员方法 getMethod(name, class []) --- 获取指定参数的public成员方法 -
获取所有成员方法
getDeclaredMethods() --- 获取所有的成员方法 getMethods() --- 获取所有的public类型的成员方法 -
获取类的方法并执行
通过执行method.invoke(Object o, class [] paramType)可以调用方法执行。 eg: Class clazz = Class.forName("com.jishucai.reflection.Student"); Object o = clazz.getDeclaredConstructor().newInstance(); Method setSex = clazz.getMethod("setSex", int.class); setSex.invoke(o, 10); 对于private类型的方法 需要执行setAccessible testStudent.setAccessible(true); testStudent.invoke(o);
获取类的成员变量
-
获取单个类的成员变量
getDeclaredField(String name); --- 获取指定的成员变量,所有类型 getField(String name); --- 获取成员变量,public类型 -
获取所有的成员变量
getDeclaredFields() --- 获取所有的成员变量 getFields() --- 获取所有的public成员变量
获取类的修饰域
类Class、Method、Constructor、Field都有一个public方法int getModifiers()。该方法返回一个int类型的数,表示被修饰对象( Class、 Method、 Constructor、 Field )的修饰类型的组合值。
System.out.println("获取指定对象的修饰域");
System.out.println(Modifier.toString(studentName.getModifiers()));
Java反射的应用
-
实现动态代理
// 实现接口 public interface SomeService { public void eat(String food); } // 接口实现类 public class SomeServiceImpl implements SomeService{ @Override public void eat(String food) { System.out.println("猫吃" + food); } } // 代理类 public class SomeInvocationHandler implements InvocationHandler { private SomeService service; public SomeInvocationHandler(SomeService service) { this.service = service; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("------begin-----"); Object invoke = method.invoke(service, args); System.out.println("------end-------"); return invoke; } } // 测试类 public class TestProxy { public static void main(String[] args) { SomeService service = new SomeServiceImpl(); SomeInvocationHandler someInvocationHandler = new SomeInvocationHandler(service); SomeService proxy = (SomeService) Proxy.newProxyInstance(someInvocationHandler.getClass().getClassLoader(), service.getClass().getInterfaces(), someInvocationHandler); proxy.eat("你好"); } } -
跳过集合的编译检查
在一个存储
Integer类型数据的List中插入一个String类型数据public class TestReflect { public static void main(String[] args) throws Exception { ArrayList<Integer> list = new ArrayList<Integer>(); Method method = list.getClass().getMethod("add", Object.class); method.invoke(list, "Java反射机制实例。"); System.out.println(list.get(0)); } }