Java中的Class.forName
在做JAVA EE开发的过程中,更多的是使用框架来提高开发效率.越来越发现,之前很基础的一些东西,都忘记的差不多了.从今天开始慢慢的复习一下基础.今天在看JDBC的时候,就有一个有趣的地方,之前学的时候,也没在意.这个Class.forName究竟是什么鬼.
连接数据库几大步.看以下代码
import com.mysql.jdbc.Driver; import java.sql.*; /**
* @author honway.liu
* @date 2016/12/8 下午11:07
* @email gm100861@gmail.com
* @blog http://linuxsogood.org
*/
public class JdbcDemo { public static void main(String[] args) throws SQLException, ClassNotFoundException {
String url = "jdbc:mysql://127.0.0.1:3306/mydb";
String username = "root";
String password = "redhat";
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection(url, username, password);
String sql = "SELECT * FROM msg";
PreparedStatement prepareStatement = connection.prepareStatement(sql);
ResultSet resultSet = prepareStatement.executeQuery();
resultSet.next();
String address = resultSet.getString("address");
System.out.println(address);
}
}
其中第一步,搞的我有点想不通.为啥Class.forName传入了一段字符串之后,就知道我连接的数据库是mysql? 有点不科学啊.Class.forName到底做了啥.下面就开始到源码中,一探究竟.
@CallerSensitive
public static Class<?> forName(String className)
throws ClassNotFoundException {
Class<?> caller = Reflection.getCallerClass();
return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}
发现它调用了forName0方法,继续跟踪再看看
private static native Class<?> forName0(String name, boolean initialize,
ClassLoaderloader,
Class<?> caller)
throws ClassNotFoundException;
native方法,源码也只能到此结束了.看下官方文档,怎么说吧.
https://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#forName(java.lang.String)
发现官方文档,还是描述的很清楚的.
ReturnstheClass object associatedwiththeclass or interface withthegivenstring name,
usingthegivenclass loader.
Giventhefullyqualifiednamefor a class or interface (in thesameformatreturnedbygetName)
this methodattemptsto locate, load, and linktheclass or interface.
Thespecifiedclass loaderis usedto loadtheclass or interface.
If theparameterloaderis null, theclass is loadedthroughthebootstrapclass loader.
Theclass is initializedonlyif theinitializeparameteris true and if ithasnot been
initializedearlier.
嗯,描述的还算是很清楚.返回一个给定类或者接口的一个Class对象,如果没有给定classloader,那么会使用根类加载器.如果initalize这个参数传了true,那么给定的类如果之前没有被初始化过,那么会被初始化.我们在JDBC第一步的时候,传入的参数是com.mysql.jdbc.Driver. 也就是说这个类会被初始化.我们看一下这个类里面的内容.
public class Driverextends NonRegisteringDriverimplements java.sql.Driver { static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
} public Driver() throws SQLException {
// Required for Class.forName().newInstance()
}
}
我们发现这个类也是超级简单的.一个构造函数和一个静态代码块.我们知道,类在初始化的时候,静态代码块的内容会被执行的.也就是说我们Class.forName和直接写DriverManager.registerDriver(new Driver)两者功能是等同的.我们换成这种写法.再试试看.
public class JdbcDemo { public static void main(String[] args) throws SQLException, ClassNotFoundException {
String url = "jdbc:mysql://127.0.0.1:3306/mydb";
String username = "root";
String password = "redhat";
//Class.forName("com.mysql.jdbc.Driver");
DriverManager.registerDriver(new Driver());
Connection connection = DriverManager.getConnection(url, username, password);
String sql = "SELECT * FROM msg";
PreparedStatement prepareStatement = connection.prepareStatement(sql);
ResultSet resultSet = prepareStatement.executeQuery();
resultSet.next();
String address = resultSet.getString("address");
System.out.println(address);
}
}
发现代码,还是正常的执行了.
总结一下:
Class.forName方法的作用,就是初始化给定的类.而我们给定的MySQL的Driver类中,它在静态代码块中通过JDBC的DriverManager注册了一下驱动.我们也可以直接使用JDBC的驱动管理器注册mysql驱动.从而代替使用Class.forName.
转载自:http://www.tuicool.com/articles/fqiMbyJ
Java中的Class.forName的更多相关文章
- JDBC剖析篇(1):java中的Class.forName()
一.Class.forName() 在Java中我们一般用下面这样的语句来连接数据库(以MySQL为例) Class.forName("com.mysql.jdbc.Driver" ...
- java中的Class.forName的作用
Class.forName有什么作用 Class.forName(xxx.xx.xx) 返回的是一个类 首先你要明白在java里面任何class都要装载在虚拟机上才能运行.这句话就是装载类用的(和ne ...
- java中Class对象详解和类名.class, class.forName(), getClass()区别
一直在想.class和.getClass()的区别,思索良久,有点思绪,然后有网上搜了搜,找到了如下的一篇文章,与大家分享. 原来为就是涉及到Java的反射----- Java反射学习 所谓反射,可以 ...
- Java中反射机制和Class.forName、实例对象.class(属性)、实例对象getClass()的区别
一.Java的反射机制 每个Java程序执行前都必须经过编译.加载.连接.和初始化这几个阶段,后三个阶段如下图: 其中
- java 中能否使用 动态加载的类(Class.forName) 来做类型转换?
今天同事提出了一个问题: 将对象a 转化为类型b,b 的classpath 是在配置文件中配置的,需要在运行中使用Class.forName 动态load进来,因为之前从来没有想过类似的问题,所以懵掉 ...
- java中class.forName和classLoader加载类的区分
java中class.forName和classLoader都可用来对类进行加载.前者除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块.而classLoade ...
- Java中Class.forName()的作用(转载)
http://www.360doc.com/content/10/0712/10/1720440_38421273.shtml# 使用jdbc方式连接数据库时会使用一句代码Class.forName( ...
- Java中的Socket的用法
Java中的Socket的用法 Java中的Socket分为普通的Socket和NioSocket. 普通Socket的用法 Java中的 ...
- java中的多线程
什么是多线程? 首先得知道什么是线程? 线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行.也可以把它理解为代码运行的上下文.所以线程基本上是轻量级的进程,它负责在单个程序里执行多任务. ...
随机推荐
- nginx gzip压缩配置
gzip(GNU-ZIP)是一种压缩技术.经过gzip压缩后页面大小可以变为原来的30%甚至更小,这样,用户浏览页面的时候速度会块得多.gzip 的压缩页面需要浏览器和服务器双方都支持,实际上就是服务 ...
- 对字符串进行base64加解密---基于python
本文介绍Python 2.7中的base64模块,该模块提供了基于rfc3548的Base16, 32, 64编解码的接口.官方文档,参考这里. 当前接口基于rfc3548的Base16/32/64编 ...
- 20172326『Java程序设计』课程结对编程练习_四则运算第二周阶段总结
20172326『Java程序设计』课程结对编程练习_四则运算第二周阶段总结 小组成员 20172313 余坤澎 20172332 于欣月 20172326 康皓越 小组编程照片 设计思路 通过一个E ...
- MacBook Pro 15寸常见问题及修复
苹果MacBook Pro更换SSD硬盘攻略教程 MacBook pro开机黑屏解决 苹果电脑 MAC PRO 开机黑屏了 MacBook Pro 开机后黑屏,怎么办啊 如果 Mac 无法开机 Mac ...
- SpringBoot与Swagger2整合
一.Swagger简介与优势 相信各位在公司写API文档数量应该不少,当然如果你还处在自己一个人开发前后台的年代,当我没说,如今为了前后台更好的对接,还为了以后交接方便,都有要求写API文档. Swa ...
- 复利计算C转java版
import java.util.Scanner; public class Compound_int { public static void main(String[] args) { tip() ...
- Windows下基于http的git服务器搭建-gitstack
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Windows下基于http的git服务器搭建-gitstack 本文地址:http: ...
- PHP创建对象的几种形式
创建对象的几种形式 class C1{ var $p1 = 1; //定义一个属性: } 形式1: $o1 = new C1(); //通过一个类,去new出一个对象 形式2: $o2 = new ...
- Linux 重定向输出到多个文件中
转自:http://codingstandards.iteye.com/blog/833695 用途说明 在执行Linux命令时,我们可以把输出重定向到文件中,比如 ls >a.txt,这时我们 ...
- 第208天:jQuery框架封装(一)
一.事件框架 1.DOM2 --事件流 事件流 :冒泡 捕获 1.1冒泡:事件按照从最特定的事件目标到最不特定的事件目标(document对象或者body)的顺序触发. 1.1.1浏览器兼容问题处理 ...