cc from http://blog.sina.com.cn/s/blog_60f823dd0100ozuz.html
Class.forName(xxx.xx.xx) 返回一个类
首先你要明白在java里面任何class都要装载在虚拟机上才能运行。这句话就是装载类用的(和new 不一样,要分清楚)。
至于什么时候用,可以考虑一下这个问题,给出一个字符串变量,它代表一个类的包名和类名,怎么实例化它?只有提到的这个方法了,不过要再加一点。
A a = (A)Class.forName("pacage.A").newInstance();
这和
A a = new A();
是一样的效果。
相关的补充问题
JVM会执行静态代码段,要记住一个概念,静态代码是和class绑定的,class装载成功就表示执行了静态代码了,以后也就不会再走这段静态代码了。
Class.forName(xxx.xx.xx) 返回的是一个类
Class.forName(xxx.xx.xx);的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段,动态加载和创建Class 对象,比如想根据用户输入的字符串来创建对象
String str = 用户输入的字符串
Class t = Class.forName(str);
t.newInstance();
在初始化一个类,生成一个实例的时候,newInstance()方法和new关键字除了一个是方法,一个是关键字外,最主要有什么区别?
它们的区别在于创建对象的方式不一样,前者是使用类加载机制,后者是创建一个新类。
那么为什么会有两种创建对象方式?
这主要考虑到软件的可伸缩、可扩展和可重用等软件设计思想。
Java中工厂模式经常使用newInstance()方法来创建对象,因此从为什么要使用工厂模式上可以找到具体答案。 例如:
class c = Class.forName(“Example”);
factory = (ExampleInterface)c.newInstance();
其中ExampleInterface是Example的接口,可以写成如下形式:
String className = "Example";
class c = Class.forName(className);
factory = (ExampleInterface)c.newInstance();
进一步可以写成如下形式:
String className = readfromXMlConfig;//从xml 配置文件中获得字符串
class c = Class.forName(className);
factory = (ExampleInterface)c.newInstance();
上面代码已经不存在Example的类名称,它的优点是,无论Example类怎么变化,上述代码不变,甚至可以更换Example的兄弟类Example2 , Example3 , Example4……,
只要它们继承ExampleInterface也就是factory就可以。
从JVM的角度看,使用关键字new创建一个类的时候,这个类可以没有被加载。但是使用newInstance()方法的时候,就必须保证:1、这个类已经加载;2、这个类已经连接了。
而完成上面两个步骤的正是Class的静态方法forName()所完成的,这个静态方法调用了启动类加载器,即加载 java API的那个加载器。
现在可以看出,newInstance()实际上是把new这个方式分解为两步,即首先调用Class加载方法加载某个类,然后实例化。
分步的好处是显而易见的:可以在调用class的静态加载方法forName时获得更好的灵活性,提供给了一种降耦的手段。
最后用最简单的描述来区分new关键字和newInstance()方法的区别:
newInstance: 弱类型。低效率。只能调用无参构造。
new: 强类型。相对高效。能调用任何public构造。
forName() 和 ClassLoader 的 loadClass 方法。
为什么 forName()是会执行static语句?
因为默认情况它总是初始化这个被装载的类。
关于forName()方法
这个方法总是返回要加载的类的Class类的实例
1、forName(String className)单参数时, initialize=true
a.总是使用当前类装载器(也就是装载执行forName()请求的类的类装载器)
b.总是初始化这个被装载的类(当然也包括:装载、连接、初始化)
2、forName(String className, boolean initialize, ClassLoader loader)
a.loader指定装载参数类所用的类装载器,如果null则用bootstrp装载器。
b.initialize=true时,肯定连接,而且初始化了;
c.false时,绝对不会初始化,但是可能被连接了,有个例外,如果在调用这个forName()前,已经被初始化了,那么返回的类型也肯定是被初始化的(当然,暗含着:
被同一个loader所装载的,而且该类被初始化了)
关于用户自定义的类装载器的loadClass()方法
1、loadClass(String name)单参数时, resolve=false
a.如果该类已经被该类装载器所装载,那么,返回这个已经被装载的类型的Class的实例,否则,就用这个自定义的类装载器来装载这个class,这时不知道是否被连接。绝对不会被初始化
b.这时唯一可以保证的是,这个类被装载了。但是不知道这个类是不是被连接和初始化了
2、loadClass(String name, boolean resolve)
a.resolve=true时,则保证已经装载,而且已经连接了。
resolve=falses时,则仅仅是去装载这个类,不关心是否连接了,所以此时可能被连接了,也可能没有被连接
相关推荐
在本篇中,我们将深入探讨如何在Java项目中使用UCanAccess库来连接和操作Access数据库,并重点讲解在JDK1.8及更高版本中的应用。 UCanAccess是一个开源的Java库,它允许Java应用程序直接读写.MDB和.MDE格式的Access...
此外,随着JDBC 4.0及更高版本的引入,驱动自动加载功能(通过`service-provider`机制)使得不再需要手动调用`Class.forName()`来加载驱动。 总的来说,JDBC是Java开发中不可或缺的一部分,它为开发者提供了一种...
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); String url = "jdbc:oracle:thin:@localhost:1521:orcl"; String user = "test"; String password = "test"; Connection conn = ...
这可以通过`Class.forName`使用类全名或直接使用类名(如`int.class`)或基本类型的`TYPE`字段(如`Integer.TYPE`)来完成。 2. 通过`Class`对象获取类的成员信息,例如方法、字段、构造器等。例如,`...
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); // 设置连接参数 String url = "jdbc:oracle:thin:@localhost:1521:orcl"; // orcl为Oracle SID String user = "test"; String password = "test...
本篇文章将详细讲解如何使用纯Java连接Excel,并介绍压缩包内的相关资源。 纯Java连接Excel通常指的是通过Java代码操作Excel文件,而无需依赖外部组件或工具,如Microsoft Office。这主要依赖于Apache POI库,它是...
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver"); //加载驱动器 Connection con=DriverManager.getConnection(dbURL,user,password); //获取连接 DatabaseMetaData dbmd=con.getMetaData(); /...
Class<?> c = Class.forName("org.lxh.demo.classdemo02.Person"); Person p = (Person) c.newInstance(); ``` 如果类有带参数的构造器,我们需要使用`Constructor`对象来实例化。首先,通过`getConstructors()`或`...
通常,我们需要将达梦提供的JDBC驱动Jar添加到项目中,然后类似地使用`Class.forName()`和`DriverManager.getConnection()`建立连接。 在实际应用中,这些配置信息通常会被存储在配置文件(如application....
在所有上述例子中,`Class.forName()`方法用于加载相应的JDBC驱动类,`DriverManager.getConnection()`则用于建立实际的数据库连接。确保在运行代码前,已经将对应的JDBC驱动库(JAR文件)添加到项目的类路径中。 ...
- 加载驱动:使用`Class.forName()`方法加载驱动类,例如`Class.forName("com.mysql.jdbc.Driver")`。这个方法会确保JVM能够找到并初始化指定的类,使得后续的数据库连接成为可能。 - 获取连接:使用`...
Class.forName("oracle.jdbc.driver.OracleDriver"); Connection conn = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:ORCL", "username", "password"); ``` 3. **DerBy**: 内嵌在Java中...
例如,我们可以通过`Class.forName()`方法根据类名动态加载类,或者通过对象的`getClass()`方法获取其运行时的类信息。 在提供的代码实例中,定义了一个名为`Phone`的类,该类实现了`List`接口。尽管这个实现并不...
2. 加载驱动:使用`Class.forName()`加载驱动类。 3. 创建连接:使用`DriverManager.getConnection()`方法创建数据库连接,提供URL、用户名和密码。 ```java Class.forName(...
通过`Class.forName()`方法,我们可以根据类名动态加载类,例如`Class<?> personClass = Class.forName("com.example.Person")`。 2. **获取构造器**:`Class`对象提供了访问其构造器的方法,如`Constructor[] ...
Class.forName("oracle.jdbc.driver.OracleDriver"); Connection conn = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:ORCL", "username", "password"); ``` 其中,`ORCL`是Oracle服务名,...
Class.forName("oracle.jdbc.driver.OracleDriver"); Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@hostname:port:sid", "username", "password"); ``` 3. **SQL Server**:Microsoft SQL...
总结起来,JSP连接数据库主要涉及两个关键步骤:加载合适的数据库驱动(如`Class.forName()`)和建立数据库连接(如`DriverManager.getConnection()`)。不同的数据库需要不同的驱动和连接URL。对于Access,可以通过...
- 使用`Class.forName("类名")`方法,例如`Class.forName("java.lang.String")`。 2. **获取类的各种组件**:一旦获得了`Class`对象,就可以使用它来获取类的各种组件,包括构造方法、方法、成员变量等。 3. **操作...
这里使用了 `Class.forName()` 方法来加载 MySQL 的 JDBC 驱动。`com.mysql.cj.jdbc.Driver` 是 MySQL 的 JDBC 驱动类。 二、连接数据库 连接数据库需要提供连接地址、用户名和密码。连接数据库的代码为: ``` ...