简单提问在线等:类加载

bocai17 2009-07-08 06:45:01
一个类被加载的时候,有那些被加进来了,具体到我这个程序,只讨论这个类被加载时的情况:
先是初始化代码块,然后是静态成员,是吗?
package pro.jdbc;

import java.sql.*;

public class JdbcUtils {
private static String driver = "com.mysql.jdbc.Driver";
private static String url = "jdbc:mysql://localhost:3306/jdbc";
private static String user = "root";
private static String password = "zhangwei";

private JdbcUtils() {
}

static {
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
throw new ExceptionInInitializerError(e);
}
}

public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, user, password);
}

public static void free(ResultSet rs, Statement stat, Connection conn) {
if (rs != null)
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (stat != null)
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (conn != null)
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
...全文
32 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
冰思雨 2009-07-08
  • 打赏
  • 举报
回复

public void free(ResultSet rs, Statement stat, Connection conn) {
if (rs != null)
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
if (stat != null)
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
if (conn != null)
connectionPool.addLast(conn);
}
bocai17 2009-07-08
  • 打赏
  • 举报
回复
我自己测试出来了,是回收出了问题,正在解决中
bocai17 2009-07-08
  • 打赏
  • 举报
回复
楼上说得好,不过我的本意就是只让它执行一次,意思就是在类加载的时候就有5个connection,在没有并发线程的情况下,我每得到一个池里的connection,都进行回收,那么应该是够用的啊,可是这个异常却说里面没有了。。。
云上飞翔 2009-07-08
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 bocai17 的回复:]
在线等,最终问题了,为什么,我用这个写出来的工具类的时候老是报错,分析了半天也没分析出来,这个是我写好的工具类,第二个是我用来测试的,老是出这个错误java.util.NoSuchElementException
[/Quote]
答:你这样写,当然会出这个错误java.util.NoSuchElementException了
你要将代码:
for (int i = 0; i < 5; i++) {
connectionPool.addLast(create());
}

从static代码块中移走,移到 public MyConnectionPool() 构造方法中。即构造方法中应为:

try{
for (int i = 0; i < 5; i++) {
connectionPool.addLast(create());
}
}catch (Exception e) {
throw new ExceptionInInitializerError(e);
}

原因是:
static代码块只执行一次,而构造器MyConnectionPool() 每new一次都执行。而你的代码代码中:Class.forName()只要执行一次,而那个for()循环是要每new一次都要执行的。
holsten32 2009-07-08
  • 打赏
  • 举报
回复
bocai17 2009-07-08
  • 打赏
  • 举报
回复
本来只想做个测试,结果出了这么个大问题啊,请教各位大大,帮我分析下,小弟感激
bocai17 2009-07-08
  • 打赏
  • 举报
回复
在线等,最终问题了,为什么,我用这个写出来的工具类的时候老是报错,分析了半天也没分析出来,这个是我写好的工具类,第二个是我用来测试的,老是出这个错误java.util.NoSuchElementException
package pro.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.LinkedList;

public class MyConnectionPool {
private static String driver = "com.mysql.jdbc.Driver";
private static String url = "jdbc:mysql://localhost:3306/jdbc";
private static String user = "root";
private static String password = "**";
private static LinkedList<Connection> connectionPool = new LinkedList<Connection>();

public MyConnectionPool() {
}

static {
try {
Class.forName(driver);
for (int i = 0; i < 5; i++) {
connectionPool.addLast(create());
}
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}

private static Connection create() throws SQLException {
return DriverManager.getConnection(url, user, password);
}

public Connection getConnection() {
return connectionPool.removeFirst();
}

public void free(ResultSet rs, Statement stat, Connection conn) {
if (rs != null)
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (stat != null)
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (conn != null)
connectionPool.addLast(conn);
}
}
}
}

package pro.jdbc;

import java.sql.Connection;
import java.sql.SQLException;

public class ConnectionTest {
public static void main(String[] args) throws SQLException {
Connection conn = null;
long start = System.currentTimeMillis();
for (int i = 0; i < 10; i++) {
MyConnectionPool cPool = new MyConnectionPool();
conn = cPool.getConnection();
System.out.println(conn);
cPool.free(null, null, conn);
}
long end = System.currentTimeMillis();
//运行出来为2610秒,下面,改造工具类,引入连接池的概念
System.out.println("the time of create connection is :" + (end - start));
}

}

bocai17 2009-07-08
  • 打赏
  • 举报
回复
明白了,谢谢
ZangXT 2009-07-08
  • 打赏
  • 举报
回复
2楼说的很清楚了,“静态成员变量与static语句块是按定义时的先后次序来初始化的。”
再说static语句块中 Class.forName(driver);必须等driver初始化后执行才有意义,所以才这么安排。
bocai17 2009-07-08
  • 打赏
  • 举报
回复
谢谢,能够说明为什么static语句块为什么在后面吗?请大家伙来发表下意见,我在写另外一个工具类,帮我确认下2楼的答案,在线急等
云上飞翔 2009-07-08
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 bocai17 的回复:]
只要这个类被加载了,是不是先static语句块,然后那些一堆的静态成员变量方法都加进来了????
[/Quote]
答:对于你的这个类,真实情况是:这个类被加载了,然后是,那些一堆的静态成员变量初始化(如:driver = "com.mysql.jdbc.Driver";等),然后才是:static语句块。即:静态成员变量与static语句块是按定义时的先后次序来初始化的。
bocai17 2009-07-08
  • 打赏
  • 举报
回复
只要这个类被加载了,是不是先static语句块,然后那些一堆的静态成员变量方法都加进来了????

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧