1.反射
1.1什么是反射
反射是框架设计的灵魂(使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)),框架:它是一个半成品,可以拿来使用,添加上自己的业务代码。提高开发效率。
反射就是把类中成员抽取成其他类的过程即把java类中的各种成分映射成一个个的Java对象
好处:1.可以在程序运行过程中,操作这些对象
2.可以解耦,提高程序的可扩展性
1.2获取反射类对象
三种方式获得反射类对象
(1).第一种方式:通过Class.forName获取反射类对象
Class.forName("全路径")
如 Class<?> aClass = Class.forName("demo01.Student");
(2)第二种方式 通过类名调用.class获取反射对象
类名.class获取
如 Class<Student> aClass1 = Student.class;
(3)第三种方式 通过对象获取发射类对象
对象.getClass();
如 Student student = new Student();
Class<? extends Student> aClass2 = student.getClass();
Class<?> aClass = Class.forName("demo01.Student");
//第二种方式 通过类名调用.class获取反射对象
Class<Student> aClass1 = Student.class;
//第三种方式 通过对象获取发射类对象
Student student = new Student();
Class<? extends Student> aClass2 = student.getClass();
//上面三个反射对象的引用地址是否一致? 是一致的。 一个类只会被加在到内存中一次。
System.out.println(aClass==aClass1);
System.out.println(aClass2==aClass1);
1.3通过反射类获取对应的类对象
public class Student extends People{
private String name;
public int age;
public void show(){
System.out.println(name+"==="+age);
}
}
class People{
public String address;
private int sex;
}
Class<Student> aClass1 = Student.class;
//2.由反射类创建类对象---调用无参构造函数
Student student1 = aClass1.newInstance();
1.4通过反射类获取对应的Filed属性对象
Class<Student> aClass1 = Student.class;
//获得本类中指定的属性对象
Field name = aClass1.getDeclaredField("name");
System.out.println(name);
//获得本类中全部属性对象
Field[] declaredFields = aClass1.getDeclaredFields();
for (Field field:declaredFields) {
System.out.println(field);
}
//获取本类以及父类中指定属性----必须为public修饰的对象
Field age = aClass1.getField("age");
System.out.println(age);
//获取本类以及父类中全部属性----必须为public修饰的对象
Field[] fields = aClass1.getFields();
for (Field field:fields) {
System.out.println(field);
}
1.5 Field属性对象中常见的方法。
getName():获取属性名
setAccessible(true):设置属性可访问。
set(o,v):为对象o的属性赋值v
get(o):获取对象o的属性值
//1.获取属性的名称
Class<Student> studentClass = Student.class;
Field declaredName = studentClass.getDeclaredField("name");
System.out.println(declaredName.getName());
System.out.println("===========");
//2.为属性赋值
Student stu = studentClass.newInstance();
declaredName.setAccessible(true);//为declaredName设置可访问权限,打破了封装性
declaredName.set(stu,"zs");
System.out.println(stu);
//3.获取属性值
Object o = declaredName.get(stu);
System.out.println(o);
1.6通过反射获取对应的Method方法对象
Class<Student> aClass = Student.class;
//获取本类中所有public修饰的方法
Method method = aClass.getMethod("show");
System.out.println(method);
//获取父类中的equals方法对象
Method equals = aClass.getMethod("equals", Object.class);
System.out.println(equals);
//获取本类和父类中所有public修饰的方法
Method[] methods = aClass.getMethods();
for (Method method1:methods) {
System.out.println(method1);
}
//获取本类中指定的方法。
//无参方法
Method method1 = aClass.getDeclaredMethod("show");
System.out.println(method);
System.out.println("============");
//有参方法
Method setName = aClass.getDeclaredMethod("setName", String.class);
System.out.println(setName);
//获取本类中所有的方法。
Method[] declaredMethods = aClass.getDeclaredMethods();
for (Method method2:declaredMethods) {
System.out.println(method2);
}
常用方法
//method.invoke(对象,方法参数值);
//invoke(student, "ls");//回调。动态代理
setName.invoke(student, "ls");
System.out.println(student.getName());
1.7获取相应的注解对象
@MyAnnotation(value = "123",id="123",sex = 1)
public class Student extends People{
@MyAnnotation(value = "123",id="123",sex = 1)
private String name;
public int age;
public Student() {
}
public void show(){
System.out.println(name+"==="+age);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class TestStu {
public static void main(String[] args) throws Exception {
Class<Student> aClass = Student.class;
MyAnnotation annotation = aClass.getAnnotation(MyAnnotation.class);
System.out.println(annotation.value());
Field nameField = aClass.getDeclaredField("name");
MyAnnotation annotation1 = nameField.getAnnotation(MyAnnotation.class);
System.out.println(annotation1.id());
System.out.println(annotation1.value());
System.out.println(annotation1.sex());
}
}