Bootstrap

Java反射机制

一、 Class对象基本概念

        1.Java当中的类用来表示具有相同属性和方法的对象的结合,是抽象的概念。对象是类创建的,同一个类的不同对象具有不同的属性值。

        2.Java当中定义的所有类都属于同一类事物,可以用Class类来表示。

        3.对比理解:

            不同的人可以用Person类来表示:

            人---->Person

            Java当中定义的不同类可以用Class来表示:

            Java当中的类---->Class

        4.Class类的对象---字节码

            Class类的对象就是不同的类对应的字节码

总结:

反射的基础Class与class对比理解如下:

        (1)含义不同 。Class是Java程序中各个Java类的总称,是反射的基石;而class可以理解为Class的实例对象,是针对某一具体类的编译后的字节码,供JVM调用。

        (2)作用不同 。Class是一个描述类的类,用于描述类的属性、方法等;而class则用于创建类的实例对象。

        Class和class在Java中各自扮演着不同的角色。

二、获取 Class 的对象方式:3

        (1)对象名.getClass()

        Person p1=new Person(); p1.getClass();

        (2)类名.class

        Date.class

        (3)Class.forName()方法(使用较多)

        Class.forName("java.long.String”);

代码:

运行结果:

总结:

1对象名.getClass()

    任何Java对象都有一个getClass()方法,它返回该对象的运行时类的Class对象。使用getClass()方法时,不需要知道对象的静态类型,这在处理泛型或未知类型的对象时比较有用。

2、类名.class方法:

对于每个类,都有一个隐含的静态成员class,它是一个指向表示该类的Class对象的引用。该方法的好处是类型安全。

3. Class.forName()方法

    Class.forName()是一个静态方法,它根据提供的类名动态加载并返回对应的Class对象。这通常用于在运行时加载和初始化类,比如加载数据库驱动。使用Class.forName()时,必须处理ClassNotFoundException,因为指定的类可能不存在或不可访问。

无论使用哪种方法,获得的是同一个Class对象。

三、基本数据类型的Class对象

  1.Java当中的基本数据类型有:

     Byte  short  int  long  float  double  char  boolean

   他们有各自的Class对象

      例:int.class

     Void--->void.class

  2.基本数据类型对应的封装类有属性TYPE,这个属性代表了封装类所封装的基本数据类型的Class对象

   int.class=Integer.TYPE

   void.class=Void.TYPE

代码:

总结运行结果:

由此可证明:基本数据类型有对应的Class对象

总结:

        在Java中,基本数据类型不是通过类来表示的,因此它们没有直接的Class对象。基本数据类型包括byteshortintlongfloatdoublecharboolean由于这些类型不是对象,它们没有继承自Object类,也没有.class文件与之关联。然而,Java为每个基本数据类型提供了一个对应的包装类,这些包装类是ByteShortIntegerLongFloatDoubleCharacterBoolean。这些包装类都有对应的Class对象。要获取基本数据类型的Class对象,可以使用对应的包装类的.class语法。

四、反射的基本概念

        1.反射(Reflect):把Java类中的各个组成部分映射成相应的Java类

        2.一个类的组成部分包括:属性、方法、构造方法、包等。这些组成部分都会被映射成相应的类。

        3. Class 类定义了一系列方法来获取Java类的属性、方法、构造方法、包等信息,这些信息都有相应的类来表示,分别是Field、Method、Constructor、Package等。而反射又需要这些信息,因而反射离不开 Class类

        注意:表示java类组成部分的各类位于java.lang.refect包中。

总结:

        反射可以类比为“照镜子”。假如有一面镜子,可以看到自己的形象,即使不直接触摸自己,也可以通过镜子来观察自己的外貌、衣着等。这就是反射的一种简单理解:通过某种媒介(镜子)来观察或操作原本不可见或不易直接操作的对象(自己)。

五、Class对象的基本使用-1

        1.Constructor类用来描述类中所定义的构造方法, 每个类都有若干个构造方法,它们用来创建和初始化该类的新实例。Constructor 类允许我们在运行时动态地访问和调用这些构造方法。

        2.(1)得到类的所有构造方法

        Constructor constructors[]

        =Class.forName(“java.lang.String”).getConstructors();

        (2)得到类中某个具体的构造方法,在getConstructor中传入参数类型所对应的字节码

        Constructor constructors[]

        =Class.forName(“java.lang.String”).getConstructor(String.class);

        3.(1)得到类中某个具体的构造方法:当该类中还没有定义构造方法时,可以获取该类的无参构造方法。

以上代码分别输出了Person类中的构造方法的名称,以及通过该方法创建的两个Person 对象,结果如图:

输出结果的哈希编码是不一样的,证明创建了两个不同的对象

总结

   学习了如何通过反射的方式创建包,得到包的信息以及得到对应的构造方法的信息。

六、Class对象的基本使用-2

        得到类中某个具体的构造方法:在创建 Person 对象时用到了newInstance()方法,在Person类中重写toString()方法,执行上段代码,输出结果如图:

因为无参构造方法无法传参,所以都为 null。

  1. 得到类中某个具体的构造方法:有参构造方法

        Constructor constructor

        =Class.forName(“java.lang.String”).getConstructors(String.class);

        在Person类中定义一个有参的构造方法(两个参数)

运行结果:

id和name属性都有了传入的值

  1. 得到类的所有构造方法

输出结果:

由此可以得出Person类共有两个构造方法。

总结

        1.在Java中,newInstance()方法是Class类中的一个方法,用于动态地创建类的新实例。

        2.在实际使用时,可能会抛出的各种异常,例如 NoSuchMethodException(找不到指定的构造方法)、InstantiationException(构造方法不能被实例化)、IllegalAccessException(构造方法不可访问)、InvocationTargetException(构造方法调用过程中抛出异常)等。

;