反射机制在Java中的作用有哪些

  介绍

这篇文章给大家介绍反射机制在Java中的作用有哪些,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

rtti

rtti(运行时类型信息)运行时类型信息,能够在程序运行时发现和使用类型信息,把我们从只能在编译期知晓类型信息并操作的局限中解脱出来

传统的多态机制正是rtti的基本使用:假设有一个基类的形状和它的三个子类圆形,正方形,三角形,现在要把圆,正方形,三角形对象放入List中,在运行时,先把放入其中的所有对象都当作 Object 对象来处理,再自动将类型转换为 Shape。所有类型转换的正确性检查都是在运行时进行的,这也正是 RTTI 的含义所在:在运行时,识别一个对象的类型

但这样的类型转换并不彻底,Object 只是被转型为 Shape,而不是更具体的 Circle、Square、Triangle,如果我们希望得到更具体的类型呢?比如说我们现在需要旋转所有图形,但是想跳过圆形(圆形旋转没有意义),这时可以使用 RTTI 查询某个 Shape 引用所指向对象的确切类型,然后选择进行合适的处理

Class 对象

众所周知,每当我们编写并编译了一个新类,就会产生一个 Class 对象,它包含了与类有关的信息。我们可以使用 Class 对象来实现 RTTI,一旦某个类的 Class 对象被载入内存,它就可以用来创建这个类的所有对象

Class 对象都属于 Class 类型,既然它也是对象,那我们就可以获取和操控它的引用。forName() 是 Class 类的一个静态方法,我们可以使用 forName() 根据目标类的全限定名(包含包名)得到该类的 Class 对象。使用 forName() 会有一个副作用,那就是如果这个类没有被加载就会加载它,而在加载的过程中,Gum 类的 static 初始块会被执行。当 Class.forName() 找不到要加载的类,就会抛出异常

ClassNotFoundException

Class gumClass=Class.forName("Gum");

使用 Class.forName() 你不需要先持有这个类型的对象,但如果你已经拥有了目标类的对象,那就可以通过调用 getClass() 方法来获取 Class 引用,这个方法来自根类 Object,它将返回表示该对象实际类型的 Class 对象的引用

Gum gum=new Gum();

Class gumClass=gum.getClass();

另外,你还可以调用 getSuperclass() 方法来得到父类的 class 对象,再用父类的 Class 对象调用该方法,重复多次,你就可以得到一个完整的类继承结构

Class 对象的 newInstance() 方法可以让你在不知道一个的确切类型的时候创建这个类的对象,使用 newInstance() 来创建的类,必须带有无参数的构造器

Object obj=gumClass.newInstance();

当然,由于得到的是 Object 的引用,目前你只能给它发送 Object 对象能接受的调用。如果你想请求具体对象才有的调用,你就得先获取该对象的更多类型信息,并执行转型

Java 还提供了另一种生成类对象的引用:类字面常量,这样做不仅更简单,而且更安全,因为它在编译时就会收到检查(不用放在 try 语句块中),而且根除了对 forName() 方法的调用,效率更高

Class gumClass=Gum.class;

类字面常量不仅可以用于普通类,也可以用于接口、数组以及基本数据类型。对于基本数据类型的包装类,还有一个标准字段 Type,Type 字段是一个引用,指向对应基本数据类型的 Class 对象,例如 int.class 就等价于 Integer.类型。还有一点值得注意的是:使用. Class语法来获得对类对象的引用不会触发初始化

到这里我们都知道了,阶级引用总是指向某个类对象,而类对象可以用于产生类的实例。不过自从Java引入泛型以后,我们就可以使用泛型类对引用所指向的类对象的类型进行限定,让它的类型变得更具体些

类intClass=int.class;
  ClassgenericIntClass=int.class;
  intClass=genericIntClass;//同一个东西//genericIntClass=双。类非法

好了,既然拿到了类对象,那我们就可以这个类的类型信息,常用的方法如下:

方法用途asSubclass(类把传递的类的对象转换成代表其子类的对象演员把对象转换成代表类或是接口的对象getClassLoader()获得类的加载器getclass()返回一个数组,数组中包含该类中所有公共类和接口类的对象getDeclaredClasses()返回一个数组,数组中包含该类中所有类和接口类的对象forName(字符串名称)根据类名返回类的对象getName()获得类的完整路径名字newInstance()创建类的实例getPackage()获得类的包getSimpleName()获得类的名字getSuperclass()获得当前类继承的父类的名字getinterface()获得当前类实现的类或是接口

反射机制在Java中的作用有哪些