Class.forName的含义

Class.forName(xxx.xx.xx) 返回的是一个类, .newInstance() 后才创建一个对象 Class.forName(xxx.xx.xx);的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段


Class aClass = Class.forName(xxx.xx.xx);
Object anInstance = aClass.newInstance();


Class.forName("").newInstance()返回的是object
but there is some limit for this method to create instance
that is your class constructor should no contain parameters, and you should cast the instance manually.

Class Driver{
protected static Driver current;
public static Driver getDriver(){
return current;
}
}

Class MyDriver extends Driver{
static{
Driver.current=new MyDriver();
}
MyDriver(){}
}

用时:
Class.forName("MyDriver");
Driver d=Driver.getDriver();

有的jdbc连接数据库的写法里是Class.forName(xxx.xx.xx);而有一些:Class.forName(xxx.xx.xx).newInstance(),为什么会有这两种写法呢?

Class.forName(xxx.xx.xx) 返回的是一个类,
.newInstance() 后才创建一个对象

Class.forName(xxx.xx.xx);的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段

在JDBC规范中明确要求这个Driver类必须向DriverManager注册自己,即任何一个JDBC Driver的Driver类的代码都必须类似如下:
public class MyJDBCDriver implements Driver {
static {
DriverManager.registerDriver(new MyJDBCDriver());
}
}

所以我们在使用JDBC时只需要Class.forName(XXX.XXX);就可以了

we just want to load the driver to jvm only, but not need to user the instance of driver, so call Class.forName(xxx.xx.xx) is enough, if you call Class.forName(xxx.xx.xx).newInstance(), the result will same as calling Class.forName(xxx.xx.xx), because Class.forName(xxx.xx.xx).newInstance() will load driver first, and then create instance, but the instacne you will never use in usual, so you need not to create it.

在JDBC驱动中,有一块静态代码,也叫静态初始化块,它执行的时间是当class调入到内存中就执行(你可以想像成,当类调用到内存后就执行一个方法)。所以很多人把jdbc driver调入到内存中,再实例化对象是没有意义的。
<think>好的,我现在需要解释用户提供的Java代码:`Class<?> c = Class.forName("Reflect.Son");`。首先,我得拆解这段代码的各个部分,理解每个关键字和方法的作用,然后组织成一个清晰的解释结构。用户之前询问了关于`main`方法的内容,现在这个问题涉及Java反射机制,可能需要从基础开始解释,确保用户理解反射的概念以及`Class.forName`的作用。 首先,`Class<?> c`这部分声明了一个Class类型的变量c,使用泛型`<?>`表示不确定具体类,但这里应该是指`Son`类。然后,`Class.forName("Reflect.Son")`是调用Class类的静态方法forName,参数是全限定类名"Reflect.Son"。这里需要注意包结构是否正确,可能用户的实际代码中"Reflect"是包名,而"Son"是该包下的类。需要解释forName方法的作用,即动态加载类,并返回对应的Class对象。 接下来要考虑用户可能的疑问点,比如反射的基本概念,为什么使用反射,以及Class对象的作用。可能需要提到反射的用途,如动态加载类、获取类信息、创建实例、调用方法等。同时,需要指出`forName`方法可能抛出ClassNotFoundException异常,但用户提供的代码中没有处理,所以可能需要提醒异常处理的重要性。 还要注意用户之前的问题涉及到`main`方法中的异常声明,这里是否应该提及异常处理的不同方式,比如try-catch块或者在方法签名中声明抛出。用户提供的代码中没有处理异常,但实际开发中应该如何处理? 另外,需要解释`Class<?>`中的通配符,为什么使用`<?>`,以及Java中泛型在反射中的应用。可能用户对泛型在这里的作用不太清楚,需要简单说明。 可能还需要举例说明,比如加载类后的操作,如实例化对象、调用方法等,让用户理解这个语句在实际中的应用场景。例如,获取Class对象后,可以通过`c.newInstance()`创建实例(虽然该方法已过时,推荐使用`getDeclaredConstructor().newInstance()`),或者获取类的方法、字段等。 同时,需要指出`Class.forName`会触发类的初始化,即执行静态代码块和静态变量的初始化,这一点也很重要,可能影响程序行为,特别是当类加载时有静态代码块时。 总结下来,回答的结构应该是先分解代码各部分,解释每个部分的作用,然后讨论相关概念,如反射、Class对象、异常处理,最后给出应用示例和注意事项。这样用户能够逐步理解这段代码的含义和用途,以及在实际开发中的应用场景。</think>以下是对代码`Class<?> c = Class.forName("Reflect.Son");`的分步解释: --- ### 1. **代码功能概述** 此代码通过**Java反射机制**动态加载名为`Reflect.Son`的类,并返回对应的`Class`对象。这是反射操作中最基础且关键的一步。 --- ### 2. **代码拆解分析** #### ① `Class<?> c` - **`Class`类型**:Java中表示类元数据的特殊类,包含类的结构信息(字段、方法、构造器等)。 - **泛型`<?>`**:表示不确定具体类类型(通配符),此处实际类型由`forName`方法动态确定。 #### ② `Class.forName("Reflect.Son")` - **静态方法`forName`**:属于`java.lang.Class`类,通过全限定类名(包名+类名)加载类。 - **参数`"Reflect.Son"`**:表示要加载的类路径: - 包结构:`Reflect`是包名 - 类名:`Son`是该包下的具体类 - 要求:类必须存在于类路径(classpath)中,否则抛出`ClassNotFoundException` --- ### 3. **反射核心特性** - **动态加载**:运行时才确定具体要操作的类(而非编译时绑定)。 - **典型用途**: ```java // 通过Class对象创建实例(旧方式,JDK9+已废弃) Son obj = (Son) c.newInstance(); // 新推荐方式:通过构造器创建实例 Constructor<Son> constructor = c.getDeclaredConstructor(); Son obj = constructor.newInstance(); ``` - 访问私有成员、动态调用方法、实现框架(如Spring依赖注入)等。 --- ### 4. **异常处理** 代码未显式处理异常,但实际开发中必须捕获`ClassNotFoundException`: ```java try { Class<?> c = Class.forName("Reflect.Son"); } catch (ClassNotFoundException e) { System.out.println("类未找到: " + e.getMessage()); } ``` --- ### 5. **类初始化影响** `Class.forName`会触发类的**静态初始化块**(static块)执行: ```java class Son { static { System.out.println("Son类静态代码块已执行"); } } ``` 执行代码`Class.forName("Reflect.Son")`时,控制台会输出上述静态块内容。 --- ### 6. **实际应用场景** - **插件化开发**:动态加载外部JAR中的类 - **数据库驱动注册**:JDBC通过`Class.forName("com.mysql.jdbc.Driver")`注册驱动 - **配置文件驱动**:根据配置文件的类名动态创建对象 是否需要进一步解释反射的具体操作(如获取方法/字段)或类加载机制?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值