打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
运行时类型识别——Class类(动态加载类)

一、RTTI

RTTI(Run_Time Type Identification 运行时类型识别):

   RTTI是任何一门面对对象语言都必须提供的功能。不仅系统本身要利用该功能来识别目前正在运行的对象真正所属的类别,程序员有时候也需要利用这一机制来识别对象,以设计程序作出适当的反应。

   Java在运行期间查找对象和类的信息,主要采取以下两种形式:

   (1)采用传统的RTTI,它假定我们已在编译和运行期间拥有所有类型

   (2)采用Java特有的“反射”机制,利用它可在运行期独立查找类信息。

说简单点,Java提供了两种方式来获取对象的信息:一种是利用传统的方法;一种是利用反射机制。

二、Class

        Java API中这么解释Class类:

  Class 类的实例表示正在运行的 Java 应用程序中的类和接口, 枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该Class 对象。 基本的 Java 类型(booleanbytecharshortintlongfloatdouble)和关键字void 也表示为 Class 对象。

注意:Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的defineClass 方法自动构造的

        为了理解RTTI在Java例如何工作,首先必须了解类型信息在运行期间是如何表示的。只要用到一个名为'Class'的特殊形式的对象,这个对象包含了与类有关的信息(有时候也把它叫作“元类”)。事实上,要用Class类创建属于某个类的全部“常规”或“普通”对象。

       任何一个作为程序一部分的类,都有一个Class对象。换言之,每次写一个新类时,同时也会创建一个Class对象(更恰当的说,是保存在一个完全同名的.class文件中)。在运行期间,一旦程序员想要生成某一个类的对象,用于执行程序的Java虚拟机(JVM)首先就会检查该类型的Class对象是否已经载入。若尚未载入,JVM就会查找同名的.class文件,并将其载入。所以,Java程序启动时并不是完全载入的,这一点与许多传统语言不同。一旦该类型的Class对象进入内存,就用它创建该类型的所有对象。

三、Class动态加载类的三种方法

(1)类名.Class

(2)类型.getClass()

(3)Class.forName('类名')  (这里的类名表示具体类名,所以要加上包名)

补充:

静态加载类和动态加载类:

        编译时刻加载的类是静态加载类,例如用new关键字创建的对象要通过编译器的静态检查,如果编译时该类不存在,那么使用该对象的类也无法通过编译。

       运行时刻加载的类是动态类,在编译的时候不会进行判断,只有在运行时才会进行判断,假设该类不存在,在运行时才会报错。

例如下面的例子:

Candy.java文件

package com.test;public class Candy { static{ System.out.println('Loading Candy in static block'); } public static void main(String[] args){ System.out.println('Loading Candy in main method'); }}

LoadClass.java文件:

package com.test;public class LoadClass {	public static void main(String[] args){		System.out.println('Before loding Candy');		try {			//加载Candy对象			Class.forName('com.test.Candy');		} catch (ClassNotFoundException e) {			e.printStackTrace();		}	}}
运行结果如下:

Before loding Candy
Loading Candy in static block

从程序的输出结果来看,用这种方式和new 来创建对象没什么区别。其实,二者之间有很大的区别,用new 关键字创建对象要通过编译器静态检查,如果编译时Candy类不存在,那么使用Candy类对象的类LoadClass也无法通过编译。而forName()方法时动态加载,即便编译时Candy类不存在,编译也是可以通过的,只是在运行时刻会抛出异常。

注意:使用forName()方法存在一个问题,它返回的是一个Class类型,而不是加载的那个类型。所以,无法做出下面的声明:

Candy candy=Class.forName('com.test.Candy');
而只能写为:
Class candy=Class.forName('com.test.Candy');
也就是说,candy无法直接使用Candy类中定义的方法。解决的办法是利用反射机制,不过这比直接用new来创建对象要麻烦得多。所以,用forName()加载对象多用在加载驱动程序的情况下(例如,加载数据库驱动)

下面举个例子熟悉一下Class动态加载类的方法:

package com.baseType;public class baseClass { public static void main(String[] args){ Class c1=int.class; //int的类类型 Class c2=String.class; //String类的类类型 Class c3=double.class; //double的类类型 Class c4=Double.class; //Double类的类类型 Class c5=void.class; //关键字void的类类型 //打印类类型的具体名称 System.out.println(c1.getName()); //int System.out.println(c2.getName()); //java.lang.String System.out.println(c3.getName()); //double System.out.println(c4.getName()); //java.lang.Double System.out.println(c5.getName()); //void //不带包名的类名称 System.out.println(c2.getSimpleName()); //String System.out.println(c4.getSimpleName()); //Double }}


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
深入理解Java类型信息(Class对象)与反射机制
类名.this与类名.class
深入理解Java反射机制
Java中Class类与Object类之间有什么关系?
java中Class对象详解和类名.class, class.forName(), getClass()区别
Java之反射技术
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服