反射定义
Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,这种动态获取信息以及动态调用对象方法的功能称为java语言的反射(reflection)机制。
总结 : 反射就是通过非常规手段 ,拿到一个类不提供给你的属性或方法 - 是一把双刃剑
反射获取对象的过程
反射怎样获取一个类的属性与方法 :
Java文件被编译后,生成了.class文件,JVM此时就要去解读.class文件 ,被编译后的Java文件.class也被JVM解析为一个对象,这个对象就是 java.lang.Class .这样当程序在运行时,每个java文件就最终变成了Class类对象的一个实例。我们通过Java的反射机制应用到这个实例,就可以去获得甚至去添加改变这个类的属性和动作,使得这个类成为一个动态的类 .
反射的用途
- 在开发中, 获取类的私有属性或方法
- 开发各种框架
- 实现自定义注解
反射相关的类(重要)
①java.lang.Class.java : 代表类的实体,在运行的Java应用程序中表示类和接口
②java.lang.reflect.Field.java :代表类的成员变量/类的属性
③java.lang.reflect.Method.java : 代表类的方法
④ java.lang.reflect.Constructor.java : 代表类的构造方法
注:所有和反射相关的包都在 import java.lang.reflect 包下面。
反射的优缺点
优点 : 不受类的访问权限限制 , 随心所欲访问
缺点 : 随心所欲的访问在计算机中可不是好词 -会造成安全性的问题
Class类(反射机制的起源 )
Class帮助文档代表类的实体,在运行的Java应用程序中表示类和接口 .
- getClassLoader() 获得类的加载器
- getDeclaredClasses() 返回一个数组,数组中包含该类中所有类和接口类的对象(包括私有的)
- forName(String className) 根据类名返回类的对象
- newInstance() 创建类的实例
- getName() 获得类的完整路径名字
常用获得类中属性相关的方法
- getField(String name) 获得某个公有的属性对象
- getFields() 获得所有公有的属性对象
- getDeclaredField(String name) 获得某个属性对象
- getDeclaredFields() 获得所有属性对象
获得类中注解相关的方法
- getAnnotation(Class annotationClass) 返回该类中与参数类型匹配的公有注解对象
- getAnnotations() 返回该类所有的公有注解对象
- getDeclaredAnnotation(Class annotationClass) 返回该类中与参数类型匹配的所有注解对象
- getDeclaredAnnotations() 返回该类所有的注解对象.
获得类中构造器相关的方法
- getConstructor(Class…<?> parameterTypes) 获得该类中与参数类型匹配的公有构造方法
- getConstructors() 获得该类的所有公有构造方法
- getDeclaredConstructor(Class…<?> parameterTypes) 获得该类中与参数类型匹配的构造方法
- getDeclaredConstructors() 获得该类所有构造方法
获得类中方法相关的方法
- getMethod(String name, Class…<?> parameterTypes) 获得该类某个公有的方法
- getMethods() 获得该类所有公有的方法
- getDeclaredMethod(String name, Class…<?> parameterTypes) 获得该类某个方法
- getDeclaredMethods() 获得该类所有方法
反射示例
获得Class对象的三种方式
- 使用 Class.forName(“类的全路径名”); 静态方法。常用
前提:已明确类的全路径名。
- 第二种,使用 .class 方法。
说明:仅适合在编译前就已经明确要操作的 Class
- 第三种,使用类对象的 getClass() 方法
示例:
class Student{
//私有属性name
private String name = "zhangsan";
//公有属性age
public int age = 2;
//不带参数的构造方法
public Student(){
System.out.println("Student()");
}
private Student(String name,int age) {
this.name = name;
this.age = age;
System.out.println("Student()");
}
private void function(String str) {
System.out.println(str);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
反射的使用
反射的测试类
package Reflect;
class Student{
//私有属性name
private String name = "sss";
//公有属性age
public int age = 18;
//不带参数的构造方法
public Student(){
System.out.println("Student()");
}
private Student(String name,int age) {
this.name = name;
this.age = age;
System.out.println("Student(String,name)");
}
private void eat(){
System.out.println("i am big");
}
public void sleep(){
System.out.println("i am pig");
}
private void function(String str) {
System.out.println(str);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Test2 {
//一个类 只能拥有一个class对象
public static void main(String[] args) throws ClassNotFoundException {
Class<?> c1 = Class.forName("Student");
Class<?> c2 = Student.class;
Student student = new Student();
Class<?> c3 = student.getClass();
System.out.println(c1==c2);
System.out.println(c3==c2);
System.out.println(c1==c3);
}
}
反射的测试
package Reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectClassDemo {
public static void reflectNewInstance() {
try {
Class<?> c1 = Class.forName("Student");
Student student = (Student)c1.newInstance();
System.out.println("学生对象:"+student);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public static void reflectPrivateConstructor() {
try {
Class<?> c1 = Class.forName("Student");
Constructor<?> constructor = c1.getDeclaredConstructor(String.class,int.class);
constructor.setAccessible(true);
Student student = (Student)constructor.newInstance("sss",19);
System.out.println(student);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public static void reflectPrivateField() {
try {
Class<?> c1 = Class.forName("Student");
Field field = c1.getDeclaredField("name");
field.setAccessible(true);
Student student = (Student)c1.newInstance();
field.set(student,"唐老鸭");
System.out.println(student);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public static void reflectPrivateMethod() {
try {
Class<?> c1 = Class.forName("Student");
Method method = c1.getDeclaredMethod("function",String.class);
method.setAccessible(true);
Student student = (Student)c1.newInstance();
method.invoke(student,"我是一个参数!");
//System.out.println(student);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
//reflectNewInstance();
//reflectPrivateConstructor();
//reflectPrivateField();
reflectPrivateMethod();
}
}
四大测试结果