学习Class类笔记
程序员文章站
2023-12-22 23:05:16
...
一. 对于Class类我之前一直只知道有这么一个类,至于它是用来干嘛的,它的特性又是什么,我一无所知。当我学到JDBC时,出现了以下语句:
这是利用JDBC访问数据库至关重要的第一步:调用Class.forName()加载并注册Mysql的驱动程序类,向其传递要加载的JDBC驱动的类名,在运行时,类加载器从CLASSPATH环境变量中定位和加载JDBC驱动类。
对以上红色字体中的解释我只能知道要利用JDBC连接数据库就必须有这么一步,但是对于Class类的特性我还是不能理解。
查API文档得知:
[quote]Instances of the class Class represent classes and interfaces in a running Java application. An enum is a kind of class and an annotation is a kind of interface. Every array also belongs to a class that is reflected as a Class object that is shared by all arrays with the same element type and number of dimensions. The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects.
Class has no public constructor. Instead Class objects are constructed automatically by the Java Virtual Machine as classes are loaded and by calls to the defineClass method in the class loader.[/quote]
由以上API文档来理解,Class它和一般的classes一样都是继承自Object。它的实体(instance)用以表达Java程序运行时的classes和interface,也用来表达enum,array,primitive Java types(boolean,byte,char,short,int ,long.float,double)以及关键词void。
Class 没有公共构造函数。当一个class被加载时,或当加载器(class loader)的defineClass()被JVM(Java 虚拟机)调用,JVM自动产生一个Class Object。因此不能显式的声明一个Class对象。
Java程序在运行时,Java运行时系统一直对所有的对象进行所谓的运行时类型标识。这项信息记录了每个对象所属的类。虚拟机通常使用运行时类型信息选准放正确方法去执行。用来保存这些类型信息的类就是Class类。Class类封装了一个对象和接口运行时的状态,当装载类时,Class类型的对象自动创建。
[quote]虚拟机为每种类型管理一个独一无二的class对象。也就是说每个类型都有一个class对象。运行程序时,Java虚拟机首先检查所要加载的类对应的Class对象是否已经加载。如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入。
-------选自51CTO网站网友熔岩的博客文章《深入研究Java.lang.class类》[/quote]
如何获得Class对象呢?有三种方法可以获取:
1. 调用Object类的getClass()方法来得到Class对象。如:
String str = “abc”;
Class c1 = str.getClass();
2. 使用Class类的静态方法forName(String str)方法获得与字符串对应的Class对象。如:
Class c2 = Class.froName(“MyClass”);MyClass必须是接口或者类的名字。
3. 第三种方法很简单,如果T是一个Java类型,那么T.class就代表了匹配的类对象。
如:
Class c3 = Manager.class;
Class c4 = int.class;
Class c5 = Double[].class;
二. 下面是我编来用来实验的小程序。
以上运行结果为:java.lang.Class.
进行以下实验:
1. 如果把Test类的定义注释。然后删掉之前产生的Test.class文件,再次编译运行,发现将会发生:ClassNotFoundException:Test。也就是找不到Test类。这是否就验证了forName(String str)方法中的字符串必须是一个类或接口的名字??。
2. 如果把Test类的定义去掉注释,再次编译运行,得出结果,同时产生Test.class文件。然后再把Test类的定义注释,编译运行,发现不会再发生异常,成功运行。这是否验证了前面所说的:运行程序时,Java虚拟机首先检查所要加载的类对应的Class对象是否已经加载。如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入??
之前运行时已经产生Test.class文件,所以把Test类的定义注释后,再编译运行,JVM根据类名能查找到到Test.class文件。
3. 如果在forName()方法中的字符串换成“String”。编译运行,发现同样发生ClassNotFoundException。当如果换成的是”java.lang.String”,则编译运行成功。这就再次验证了forName(String str)方法中的字符串必须是一个类或接口的名字,不管是Java API中封装好的,还是你自己定义的。
[quote]参考:
1. Java API文档
2. 熔岩博客文章《深入研究java.lang.Class类》
3. 侯捷-Java反射机制[/quote]
Class.forName(“com.mysql.jdbc.Driver”);
这是利用JDBC访问数据库至关重要的第一步:调用Class.forName()加载并注册Mysql的驱动程序类,向其传递要加载的JDBC驱动的类名,在运行时,类加载器从CLASSPATH环境变量中定位和加载JDBC驱动类。
对以上红色字体中的解释我只能知道要利用JDBC连接数据库就必须有这么一步,但是对于Class类的特性我还是不能理解。
查API文档得知:
[quote]Instances of the class Class represent classes and interfaces in a running Java application. An enum is a kind of class and an annotation is a kind of interface. Every array also belongs to a class that is reflected as a Class object that is shared by all arrays with the same element type and number of dimensions. The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects.
Class has no public constructor. Instead Class objects are constructed automatically by the Java Virtual Machine as classes are loaded and by calls to the defineClass method in the class loader.[/quote]
由以上API文档来理解,Class它和一般的classes一样都是继承自Object。它的实体(instance)用以表达Java程序运行时的classes和interface,也用来表达enum,array,primitive Java types(boolean,byte,char,short,int ,long.float,double)以及关键词void。
Class 没有公共构造函数。当一个class被加载时,或当加载器(class loader)的defineClass()被JVM(Java 虚拟机)调用,JVM自动产生一个Class Object。因此不能显式的声明一个Class对象。
Java程序在运行时,Java运行时系统一直对所有的对象进行所谓的运行时类型标识。这项信息记录了每个对象所属的类。虚拟机通常使用运行时类型信息选准放正确方法去执行。用来保存这些类型信息的类就是Class类。Class类封装了一个对象和接口运行时的状态,当装载类时,Class类型的对象自动创建。
[quote]虚拟机为每种类型管理一个独一无二的class对象。也就是说每个类型都有一个class对象。运行程序时,Java虚拟机首先检查所要加载的类对应的Class对象是否已经加载。如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入。
-------选自51CTO网站网友熔岩的博客文章《深入研究Java.lang.class类》[/quote]
如何获得Class对象呢?有三种方法可以获取:
1. 调用Object类的getClass()方法来得到Class对象。如:
String str = “abc”;
Class c1 = str.getClass();
2. 使用Class类的静态方法forName(String str)方法获得与字符串对应的Class对象。如:
Class c2 = Class.froName(“MyClass”);MyClass必须是接口或者类的名字。
3. 第三种方法很简单,如果T是一个Java类型,那么T.class就代表了匹配的类对象。
如:
Class c3 = Manager.class;
Class c4 = int.class;
Class c5 = Double[].class;
二. 下面是我编来用来实验的小程序。
public class TestClass1 {
public static void main(String[] args) throws ClassNotFoundException {
Class cla = Class.forName("Test");
System.out.println(cla.getClass().getName());
}
}
class Test {
private String str;
public Test(String str) {
this.str = str;
}
public String getStr() {
return str;
}
}
以上运行结果为:java.lang.Class.
进行以下实验:
1. 如果把Test类的定义注释。然后删掉之前产生的Test.class文件,再次编译运行,发现将会发生:ClassNotFoundException:Test。也就是找不到Test类。这是否就验证了forName(String str)方法中的字符串必须是一个类或接口的名字??。
2. 如果把Test类的定义去掉注释,再次编译运行,得出结果,同时产生Test.class文件。然后再把Test类的定义注释,编译运行,发现不会再发生异常,成功运行。这是否验证了前面所说的:运行程序时,Java虚拟机首先检查所要加载的类对应的Class对象是否已经加载。如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入??
之前运行时已经产生Test.class文件,所以把Test类的定义注释后,再编译运行,JVM根据类名能查找到到Test.class文件。
3. 如果在forName()方法中的字符串换成“String”。编译运行,发现同样发生ClassNotFoundException。当如果换成的是”java.lang.String”,则编译运行成功。这就再次验证了forName(String str)方法中的字符串必须是一个类或接口的名字,不管是Java API中封装好的,还是你自己定义的。
[quote]参考:
1. Java API文档
2. 熔岩博客文章《深入研究java.lang.Class类》
3. 侯捷-Java反射机制[/quote]