likes
comments
collection
share

怎么去理解反射

作者站长头像
站长
· 阅读数 38

一、反射(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
评论
请登录