怎么去理解反射
一、反射(Reflection)的概述
1.1、定义
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法 对于任意一个对象,都能够调用它的任意一个方法和属性, 这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
即:在"运行时",通过反射机制可以动态获得到和该类型相关的各种信息。
java通常是先有类后有对象,有对象就可以调用方法或属性。反射其实是通过Class对象来调用类里面的方法。 通过反射可以调用私有方法和私有属性。大部分框架都是运用反射原理。
1.2、Class类型
java.lang.Class类
Class是对java中所有类型的抽象。即一个Class类型对象可以表示出java中任意一种类型。每种类型在加载到内存后,内存中都会生产一个与之对应的Class类型对象(有且只有一个),用来表示该类型。
每个类型都有且只有一个Class类型对象与之对应,通过这个Class类型对象就可以获得到该类型中的各种信息。Class类是Java反射的入口.。
1)表示基本类型
Class c = int.class;
System.out.println(c.isPrimitive());//true
System.out.println(c.getName());//int
注:其他基本类型的情况类似 2)表示类类型
注:s.getClass()方法返回的是变量s所指向对象的实现类型的Class对象。
Student s = new Student();
Class c1 = s.getClass();
Class c2 = Student.class;
System.out.println(c1 == c2);//true
//p指向的对象实际类型是Student
Person p = new Student();
Class c1 = p.getClass();//c1表示Student类型
Class c2 = Person.class;//c2表示Person类型
System.out.println(c1 == c2);//false
3、表示接口类型
Action a = new Student();
Class c1 = a.getClass();//c1表示Student类型
Class c2 = Action.class;//c2表示Action类型
System.out.println(c1 == c2);//false
System.out.println(c2.isInterface());//true
4、表示数组类型
int[] a = new int[4];
Class c1 = a.getClass();
Class c2 = int[].class;
System.out.println(c1 == c2);//true
System.out.println(c1.isArray());//true
Class c3 = c1.getComponentType();//c3表示该数组是使用什么类型声明出来的
System.out.println(c3.getName());//int
Student[] a = new Student[4];
Class c1 = a.getClass();
Class c2 = Student[].class;
System.out.println(c1 == c2);//true
System.out.println(c1.isArray());//true
Class c3 = c1.getComponentType();//c3表示该数组是使用什么类型声明出来的
System.out.println(c3.getName());//com.briup.test.Student
1.3、获取一个类类型的Class对象的三种方式
想要使用反射机制,就必须要先获取到该类的字节码文件对象(.class),通过字节码文件对象,就能够通过该类中的方法获取到
我们想要的所有信息(方法,属性,类名,父类名,实现的所有接口等等),每一个类对应着一个字节码文件也就对应着一个Class类型的对象,也就是字节码文件对象。
1、使用Class类中的forName方法获得
Class clazz1 = Class.forName("全限定类名");
:通过Class类中的静态方法forName,直接获取到一个类的字节码文件对象,此时该类还是源文件阶段,并没有变为字节码文件。
这种方法很灵活,只需一个String类型参数即可,而String类型的数据改变起来很容易,注意该方法是会抛出异常。
2、使用类名获得
Class clazz2 = Person.class;
:当类被加载成.class文件时,此时Person类变成了.class,在获取该字节码文件对象,也就是获取自己, 该类处于字节码阶段。
3、使用对象调用getClass方法获得
Class clazz3 = p.getClass();
:通过类的实例获取该类的字节码文件对象,该类处于创建对象阶段。
getClass是Object中的final修饰的方法,每个对象都可以调用而且不能重写
注:以上三种方法获得的同一个对象(==比较),因为每个类型内存都有且只有一个Class类型对象。
1.4、反射机制中的常见类的含义
- java.lang包下
- Class 类:对java中所有类型抽象而得来的
- Package类:对java中所有包抽象而得来的
- java.lang.reflect包下:
- Modifier类 对java中所有修饰符抽象而得来的
- Field类 对java中所有属性抽象而得来的
- Method类 对java中所有方法抽象而得来的
- Constructor类 对java中所有构造器抽象而得来的
- Array类 提供了对数组对象的动态访问
- ParameterizedType接口 在反射中表示参数化类型
例如:List Point<Long,Long>等这种带泛型的类型
转载自:https://juejin.cn/post/7173194594866167845