反射
入门
获取Class对象的三种方法
- 第一种:使用Class的静态方法forName()
- 第二种:使用类名.class
- 第三种:使用实例的getClass()方法
[示例代码]
//获取Class对象的方法一:通过Class.froName()方法获取,参数为类的全包名
Class<?> aClass1 = Class.forName("com.zssd.entity.Student");
//获取Class对象的方法二:通过类名.class获取
Class<Student> aClass2 = Student.class;
//获取Class对象的方法三:使用实例对象的getClass()方法
Student student = new Student();
Class<? extends Student> aClass3 = student.getClass();
实例化对象
- 通过newInstance方法实例化对象
- 通过构造器实例化对象
[示例代码]
//获取Class对象的方法一:通过Class.froName()方法获取,参数为类的全包名
Class<?> aClass = Class.forName("com.zssd.entity.Student");
//通过newInstance方法实例化对象
Object o = aClass.newInstance();
//获取无参构造器,通过构造器的newInstance()方法实例化对象
Constructor<?> constructor = aClass.getConstructor();
Object o1 = constructor.newInstance();
反射获取类的构造器
- 获取指定参数类型的公共构造方法(公共的):getConstructor(Class<?>... parameterTypes)
- 获取指定参数类型的构造方法:getDeclaredConstructor(Class<?>... parameterTypes)
- 获取所有构造方法(公共的):getConstructors()
- 获取所有的构造方法:getDeclaredConstructors()
[示例代码]
//获取Class对象的方法一:通过Class.froName()方法获取,参数为类的全包名
Class<?> aClass = Class.forName("com.zssd.entity.Student");
//获取指定参数类型的公共构造方法,无参以及有参
Constructor<?> constructor1 = aClass.getConstructor();
Constructor<?> constructor2 = aClass.getConstructor(String.class,Integer.class,String.class);
//获取所有公共的构造方法
Constructor<?>[] constructors = aClass.getConstructors();
//获取指定参数类型的构造方法,无参以及有参
Constructor<?> declaredConstructor1 = aClass.getDeclaredConstructor();
Constructor<?> declaredConstructor2 = aClass.getDeclaredConstructor(String.class,Integer.class,String.class);
//获取所有的构造方法
Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors();
反射获取类的成员变量
- 获取指定的成员变量(公共的):getField(String name)
- 获取指定的成员变量:getDeclaredField(String name)
- 获取所有的成员变量(公共的):getFields()
- 获取指定的成员变量:getDeclaredFields()
[示例代码]
//获取Class对象的方法一:通过Class.froName()方法获取,参数为类的全包名
Class<?> aClass = Class.forName("com.zssd.entity.Student");
//获取指定的成员变量(公共的)
Field field = aClass.getField("name");
//获取指定的成员变量
Field declaredField = aClass.getDeclaredField("name");
//获取所有的成员变量(公共的)
Field[] fields = aClass.getFields();
//获取所有的成员变量
Field[] declaredFields = aClass.getDeclaredFields();
反射获取类的方法
- 获取指定的方法(公共的):getMethod(String methodName,Class<?>... parameterTypes)
- 获取指定的方法:getDeclaredMethod(String methodName,Class<?>... parameterTypes)
- 获取所有方法(公共的,包含继承父类的方法):getMethods()
- 获取所有的方法(不包含继承父类的):getDeclaredMethods()
[示例代码]
//获取Class对象的方法一:通过Class.froName()方法获取,参数为类的全包名
Class<?> aClass = Class.forName("com.zssd.entity.Student");
//获取指定方法名的方法(公共的)
Method getName = aClass.getMethod("getName");
//获取指定方法名的方法
Method setName = aClass.getDeclaredMethod("setName", String.class);
//获取所有方法(公共的,包含继承父类的方法)
Method[] methods = aClass.getMethods();
//获取所有方法(不包含父类的方法)
Method[] declaredMethods = aClass.getDeclaredMethods();
属性赋值以及invoke()方法
[示例代码]
Field age = aClass.getDeclaredField("age");
age.setAccessible(true);
age.set(student, 20);
[示例代码]
Method setName = aClass.getMethod("setName", String.class);
setName.invoke(student, "李四");
说明:如果属性或者方法是私有的话,要想赋值或者传参成功,需要执行age.setAccessible(true).表示允许访问(谨慎使用)
反射的一些应用以及问题
-
应用:JDBC数据库的链接,java框架的使用
-
问题:
- 性能问题:java反射的性能并不好,因为主要是编译器没法对反射相关的代码做优化
- 安全问题:反射可以修改访问权限,使用反射的话通常需要程序的运行没有安全限制