`
gel543626548
  • 浏览: 3805 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

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调入到内存中,再实例化对象是没有意义的。


Class clazz = Class.forName("XXX.XXX");

ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class clazz = cl.loadClass("XXX.XXX");
都可以装载一个类那么他们的区别是什么呢?
进一步研究Class.forName()是调用
Class.forName(name, initialize, loader);也就是Class.forName("XXX.XXX"); 等同与Class.forName("XXX.XXX", true, CALLCLASS.class.getClassLoader());

第二次参数表示装载类的时候是否初始化该类, 即调用类的静态块的语句及初始化静态成员变量。

Class clazz = cl.loadClass("XXX.XXX");没有指定是否初始化的选项。只有执行clazz.newInstance();时才能够初始化类。可以说Class.forName("XXX.XXX", false, cl)执行过程是一致的。只是ClassLoader.loadClass()是更底层的操作。

看一下JDBC驱动的装载。
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbcurl");
当调用Class.forName("com.mysql.jdbc.Driver");是Driver已经被初始化并注册到DriverManager中。MySQL Driver的代码
public class Driver extends NonRegisteringDriver
     implements java.sql.Driver
{

     public Driver()
         throws SQLException
     {
     }

     static
     {
         try
         {
             DriverManager.registerDriver(new Driver());
         }
         catch(SQLException E)
         {
             throw new RuntimeException("Can't register driver!");
         }
     }
}
改修JDBC驱动的装载
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class clazz = cl.loadClass("com.mysql.jdbc.Driver");
clazz.newInstance();
Connection conn = DriverManager.getConnection("jdbcurl");
同样可以执行。但是这样就多构造了一个com.mysql.jdbc.Driver实例。同Class.forName("com.mysql.jdbc.Driver").newInstance()是一样的。是没有任何意义的。


类名.class是Class对象的句柄,每个被加载的类,在jvm中都会有一个Class对象与之相对应,如果要创建新的对象,直接使用Class对象的局部class.forName就可以了,不需要用new       类名。


在java中,每个class都有一个相应的Class对象,当编写好一个类,编译完成后,在生成的.class文件中,就产生一个class对象,用来表示这个类的类型信息。获得Class实例的三中方式:
1.利用对象调用getClass()方法获取该对象的Class实例
2.使用Class的静态方法forName(),用类的名字获取一个Class实例
3.运用.calss的方式获取Class实例,对基本数据类型的封装类,还可以采用.TYPE来获取对应的基本数据类型的Class实例

calss ClassTest
{
                public static void main(String[] args)
                {
                        /*
                        //利用对象调用getClass()方法获取该对象的Class实例
                        Point pt=new Point();               
                        Class c1=pt.getClass();
                        System.out.println(c1.getName());                        //结果:Point
               
                        //使用Class的静态方法forName(),用类的名字获取一个Class实例
                        try
                        {
                                Class c2=Class.forName("Point");
                                System.out.println(c2.getName());                //结果:Point
                        }
                        catch(Exception e)
                        {
                                e.printStackTrace();
                        }

                        //运用.calss的方式获取Class实例(类)
                        Class c3=Point.calss;
                        System.out.println(c3.getName());                        //结果:Point

                        //运用.calss的方式获取Class实例(基本类型)
                        Class c4=int.calss;
                        System.out.println(c4.getName());                        //结果:int

                        //运用.calss的方式获取Class实例(基本数据类型的封装类)
                        Class c5=Integer.TYPE;
                        System.out.println(c5.getName());                        //结果:int
               
                        Class c6=Integer.class;
                        System.out.println(c6.getName());                        //结果:java.lang.Integer
                        */
               
                        //以下结果是:          before new Point()
                                        loading point
                                        after new Point()
                                        loading Line       
                        //当new Point()的时候加载这个类,用forName构造实例的时候也加载该类。
                        System.out.println("before new Point()");
                        new Point();
                        System.out.println("after new Point()");

                        try
                        {
                                Class.forName("Line");
                        }catch(Exception e)
                        {
                                e.printStackTrace();
                        }
               
                }
}
class Point()
{
                static
                {
                        System.out.println("loading point");
                }
                int x,y;
}
class Line
{
                static
                {
                        System.out.println("loading Line");
                }
}

在运行期间,如果我们要产生某个类的对象,java虚拟机会检测该类型的Class对象是否已被加载。如果没有加载,java虚拟机会根据类的名称找到.class文件并加载它。一旦某个类型的Class对象已经被加载到内存,就可以用它来产生该类型的所有对象。
newInstance()调用内中缺省的构造方法。

newInstance()调用类中缺省的构造方法,如果要实例的对象中有了自己定义的构造方法(除重写的和默认构造方法相同的构造方法外)
创建此 Class 对象所表示的类的一个新实例
class ClassTest
{
               public static void main(String[] args)
               {
                       if(args.length!=1)
                       {
                               System.out.println("args.length!=1");
                               return;
                       }
                       try
                       {
                               Class c=Class.forName(args[0]);
                               Point pt=(Point)c.newInstance();
                               pt.output();
                       }catch(Exception e)
                       {
                               e.printStackTrace();
                       }
               }
}
class Point
{
               int x;
               int y;
               static
               {
                       System.out.println("Loading point");
               }
               void output()
               {
                       System.out.println("x="+x+",y="+y);
               }
}
当我们在命令提示符下面编译好该类之后,输入java ClassTest Point的时候,此时会输出Loading point和x=0,y=0


Class clazz = Class.forName("XXX.XXX");

ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class clazz = cl.loadClass("XXX.XXX");
都可以装载一个类那么他们的区别是什么呢?
进一步研究Class.forName()是调用
Class.forName(name, initialize, loader);也就是Class.forName("XXX.XXX"); 等同与Class.forName("XXX.XXX", true, CALLCLASS.class.getClassLoader());

第二次参数表示装载类的时候是否初始化该类, 即调用类的静态块的语句及初始化静态成员变量。

Class clazz = cl.loadClass("XXX.XXX");没有指定是否初始化的选项。只有执行clazz.newInstance();时才能够初始化类。可以说Class.forName("XXX.XXX", false, cl)执行过程是一致的。只是ClassLoader.loadClass()是更底层的操作。

看一下JDBC驱动的装载。
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbcurl");
当调用Class.forName("com.mysql.jdbc.Driver");是Driver已经被初始化并注册到DriverManager中。MySQL Driver的代码
public class Driver extends NonRegisteringDriver
          implements java.sql.Driver
{

          public Driver()
              throws SQLException
          {
          }

          static
          {
              try
              {
                  DriverManager.registerDriver(new Driver());
              }
              catch(SQLException E)
              {
                  throw new RuntimeException("Can't register driver!");
              }
          }
}
改修JDBC驱动的装载
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class clazz = cl.loadClass("com.mysql.jdbc.Driver");
clazz.newInstance();
Connection conn = DriverManager.getConnection("jdbcurl");
同样可以执行。但是这样就多构造了一个com.mysql.jdbc.Driver实例。同Class.forName("com.mysql.jdbc.Driver").newInstance()是一样的。是没有任何意义的。

分享到:
评论

相关推荐

    数据库连接字符串

    Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); String url = "jdbc:oracle:thin:@localhost:1521:orcl"; // orcl 为 Oracle SID String user = "test"; String password = "test"; Connection ...

    学习笔记汇总-JAVA

    Class.forName("oracle.jdbc.driver.OracleDriver"); String url = "jdbc:oracle:thin:@localhost:1521:orcl"; Connection conn = DriverManager.getConnection(url, "test", "test"); ``` - **DB2数据库**: `...

    java连接数据库的问题.txt

    1. **加载JDBC驱动**:首先需要通过`Class.forName()`方法加载对应的JDBC驱动。 2. **建立连接**:利用`DriverManager.getConnection()`方法建立到数据库的连接。 3. **执行SQL语句**:通过`Statement`或`...

    服务器出现java.sql.SQLException No suitable driver found for 的.pdf

    这通常是通过调用`Class.forName()`方法完成的。例如: ```java Class.forName("com.mysql.cj.jdbc.Driver"); ``` - **注意事项**: - 确保类名是正确的。对于MySQL 8.0,驱动类名为`com.mysql.cj.jdbc.Driver`。 ...

    《JAVA高级&数据库编程》题库[归纳].pdf

    在 Java 中,创建 Class 对象有三种方式:(1)使用 Class.forName() 方法,(2)使用类的 class 属性,(3)使用对象的 getClass() 方法。 二、反射机制 反射机制是 Java 语言中的一个重要机制,它允许程序在运行...

    Java面试题-基础和集合.docx

    - 可以通过对象的`.getClass()`方法或`Class.forName()`方法来获取一个类的Class对象。 - 示例代码: ```java MyClass myObject = new MyClass(); Class<?> clazz1 = myObject.getClass(); System.out.println...

    framework_intermediates

    在Android中,可以使用`Class.forName()`方法加载隐藏类,然后通过`Class.getDeclaredMethods()`获取所有方法,包括私有和隐藏的。接着,使用`Method.invoke()`方法可以在运行时执行这些方法,从而实现对隐藏接口的...

    sql驱动程序

    - 使用`Class.forName()`方法加载驱动程序,例如:`Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver")`。 - 创建数据库连接,使用`DriverManager.getConnection()`方法,提供数据库URL、用户名和密码...

    JSP com.mysql.jdbc.Driver‘. This is deprecated. The new d.pdf

    Class.forName("com.mysql.jdbc.Driver"); ``` 你需要将其更改为: ```java Class.forName("com.mysql.cj.jdbc.Driver"); ``` 同时,确保任何其他使用旧驱动的地方也进行相应的更新,包括数据源配置(DataSource...

    初中英语必背词组大全.doc

    初中英语学习过程中,掌握一些常用词组至关重要,它们不仅能帮助学生更好地理解句子含义,还能提升写作和口语表达的流畅度。以下是一些重要的初中英语词组及其应用: 1. wele to...:用于欢迎他人到达某个地方,如...

    JDBCDemo02(1).zip_jdbc_quarterj7w

    这通常通过`Class.forName()`方法来完成,例如对于MySQL,可能是`Class.forName("com.mysql.jdbc.Driver")`。 2. **建立连接**:使用`DriverManager.getConnection()`方法创建数据库连接。需要提供数据库URL、...

    java专题-反射

    Class<?> c = Class.forName(args[0]); Method[] methods = c.getDeclaredMethods(); for (Method m : methods) { System.out.println(m.toString()); } } catch (Throwable e) { System.err.println(e); } ...

    sqljdbc4.jar程序文件

    通过调用`Class.forName()`方法加载驱动,然后使用`DriverManager.getConnection()`方法建立与数据库的连接。例如: ```java Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); Connection conn = ...

    Oracle JDBC连接字符串

    通过反射机制调用`Class.forName()`方法加载驱动类,再通过`newInstance()`创建一个实例。注意,这种方式在较新的版本中已被弃用,推荐使用`DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());`...

    sqlServer连接驱动

    2. 引入SQL Server驱动:在代码中,通过`Class.forName()`方法加载驱动,例如:`Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");` 3. 创建数据库连接:使用`java.sql.DriverManager.getConnection...

    oracle 驱动包

    Class.forName("oracle.jdbc.driver.OracleDriver"); Connection conn = DriverManager.getConnection(url, username, password); System.out.println("Connected to the database!"); // 执行SQL操作... conn....

    Java软件开发实战 Java基础与案例开发详解 15-4 练习题 共5页.pdf

    - 动态创建对象:`Class<?> clazz = Class.forName("com.example.MyClass"); Object obj = clazz.newInstance();` - 调用方法:`Method method = clazz.getMethod("methodName", parameterTypes); method.invoke...

    oracle数据库的JDBC驱动

    使用这些驱动时,开发者需要在Java代码中加载对应的JDBC驱动,并通过`Class.forName()`方法注册驱动,然后创建`java.sql.Connection`对象以建立到Oracle数据库的连接。例如: ```java Class.forName("oracle.jdbc....

Global site tag (gtag.js) - Google Analytics