类名.class与Class.forName(),class.getClassLoader()

来源:互联网 发布:亚马逊 京东 淘宝 编辑:程序博客网 时间:2024/09/21 09:24
 Class对象的获取1.所有的引用数据类型(类-类型)的类名、基本数据类型都可以通过.class方式获取其 Class对象(对于基本数据类型的封装类还可以通过.TYPE 的方式获取其 Class 对象,但要注意。TYPE 实际上获取的封装类对应的基本类型的 Class 对象的引用,那么你可以判断出int.class==Integer.TYPE 返回 true,int.class==Integer.class 返回 false!),通过这种方式不会初始化静态域,使用.class、.TYPE 的方式获取 Class对象叫做类的字面常量;2.Class 的 forName(String  name)传入一个类的完整类路径也可以获得 Class 对象,但由于使用的是字符串,必须强制转换才可以获取泛型的Class<T>的 Class对象,并且你必须获取这个方法可能抛出的ClassNotFoundException异常。这种方法可以初始化静态域。3.还可通过类的对象实例下的getClass()方法来获取Class对象,即 实例名.getClass()

使用JDBC时,我们都会很自然得使用下列语句:

java 代码
  1. Class.forName("com.mysql.jdbc.Driver");   
  2. String url = "jdbc:mysql://127.0.0.1/test?useUnicode=true&characterEncoding=utf-8";   
  3. String user = "";   
  4. String psw = "";   
  5. Connection con = DriverManager.getConnection(url,user,psw);  

    为什么说很自然呢,因为无论是网上还是书本教程上得例子都是这样的,而且程序也确实正常运行了,于是大家也就心安理得的找葫芦画瓢下去了。    一定要有这一句吗?不是的,我们完全可以用这样一句代替它:

java 代码
  1. com.mysql.jdbc.Driver driver = new com.mysql.jdbc.Driver();   
  2. //or:   
  3. //new com.mysql.jdbc.Driver();   
  4. String url = "jdbc:mysql://127.0.0.1/test?useUnicode=true&characterEncoding=utf-8";   
  5. String user = "";   
  6. String psw = "";   
  7. Connection con = DriverManager.getConnection(url,user,psw);   
  8.   

    大家可能都看出个大概来了,我们只需要在调用DriverManager的getConnection方法之前,保证相应的Driver类已经被加载到jvm中,并且完成了类的初始化工作就行了,而具体是怎样实现这个功能却是没有讲究的。上面两种方法都可以实现这个功能,因此程序可以正常运行。注意了,如果我们进行如下操作,程序是不能正常运行的,因为这样仅仅使Driver类被装载到jvm中,却没有进行相应的初始化工作。

java 代码
  1. com.mysql.jdbc.Driver driver = null;   
  2. //or:   
  3. ClassLoader cl = new ClassLoader();   
  4. cl.loadClass("com.mysql.jdbc.Driver");  

     我们都知道JDBC是使用Bridge模式进行设计的,DriverManager就是其中的Abstraction,java.sql.Driver是Implementor,com.mysql.jdbc.Driver是Implementor的一个具体实现(请参考GOF的Bridge模式的描述)。大家注意了,前一个Driver是一个接口,后者却是一个类,它实现了前面的Driver接口。     Bridge模式中,Abstraction(DriverManager)是要拥有一个Implementor(Driver)的引用的,但是我们在使用过程中,并没有将Driver对象注册到DriverManager中去啊,这是怎么回事呢?jdk文档对Driver的描述中有这么一句:     When a Driver class is loaded, it should create an instance of itself and register it with the DriverManager 哦,原来是com.mysql.jdbc.Driver在装载完后自动帮我们完成了这一步骤。源代码是这样的:

java 代码
  1. package com.mysql.jdbc   
  2.   
  3. public class Driver extends NonRegisteringDriver implements java.sql.Driver {   
  4.  // ~ Static fields/initializers   
  5.  // --------------------------------------------- //   
  6.  // Register ourselves with the DriverManager   
  7.  //   
  8.  static {   
  9.     t ry {   
  10.               java.sql.DriverManager.registerDriver(new Driver());   
  11.           } catch (SQLException E) {   
  12.               throw new RuntimeException("Can't register driver!");   
  13.           }   
  14.   }   
  15. // ~ Constructors   
  16.  // -----------------------------------------------------------   
  17. /**  
  18.   * Construct a new driver and register it with DriverManager  
  19.   *   
  20.   * @throws SQLException  
  21.   *             if a database error occurs.  
  22.   */  
  23.  public Driver() throws SQLException {   
  24.      // Required for Class.forName().newInstance()   
  25.  }   
  26. }  

java是面向对象语言,面向对象的语言的宗旨就是万事万物皆对象,那么类也是一个对象,类里面的属性和方法也是对象。java里面的所

有的类都是Class类的对象,这个this.class是获得这个类相对于Class类的对象。后面的方法是获得这个类对象的加载器。

只有Class类才有getClassLoader()方法呀~ 可以这么想,我们平时讲述某某类,但是我们并没有说这个类怎么和虚拟机打交道,虚拟机怎么识别这

个类.总不能全靠字符串吧. 所以呢java就设计了Class这个类.用于虚拟机对类的管理.当一个类被虚拟机装载完毕的时候,就会创建一个Class类

的实例,对于类A就是A.class,对于类B就是B.class. Class类也提供了许多方法来获取类的信息. 要知道,类的装载器分为 "启动类装载器 ", "用

户定义装载器 ".它不止一种 Class类需要保存这些信息. getClassLoader()是用来获取这个信息的

0 0
原创粉丝点击