一个类被加载的时候,有那些被加进来了,具体到我这个程序,只讨论这个类被加载时的情况:
先是初始化代码块,然后是静态成员,是吗?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();
}
}
}
}
}

解决方案 »

  1.   

    只要这个类被加载了,是不是先static语句块,然后那些一堆的静态成员变量方法都加进来了????
      

  2.   

    答:对于你的这个类,真实情况是:这个类被加载了,然后是,那些一堆的静态成员变量初始化(如:driver = "com.mysql.jdbc.Driver";等),然后才是:static语句块。即:静态成员变量与static语句块是按定义时的先后次序来初始化的。
      

  3.   

    谢谢,能够说明为什么static语句块为什么在后面吗?请大家伙来发表下意见,我在写另外一个工具类,帮我确认下2楼的答案,在线急等
      

  4.   

    2楼说的很清楚了,“静态成员变量与static语句块是按定义时的先后次序来初始化的。”
    再说static语句块中  Class.forName(driver);必须等driver初始化后执行才有意义,所以才这么安排。
      

  5.   

    在线等,最终问题了,为什么,我用这个写出来的工具类的时候老是报错,分析了半天也没分析出来,这个是我写好的工具类,第二个是我用来测试的,老是出这个错误java.util.NoSuchElementExceptionpackage 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));
    }}
      

  6.   

    答:你这样写,当然会出这个错误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一次都要执行的。
      

  7.   

    楼上说得好,不过我的本意就是只让它执行一次,意思就是在类加载的时候就有5个connection,在没有并发线程的情况下,我每得到一个池里的connection,都进行回收,那么应该是够用的啊,可是这个异常却说里面没有了
      

  8.   


        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);
        }