iteye_963
2009-04-05 16:48 阅读 218
已采纳

关于java运行顺序的问题

打算做一个数据库连接池的实现,结果遇到了对java运行顺序理解的困惑。麻烦大家帮忙看看,具体问题在下面给出。

 

这个是工具类。

package com.jdbc.comm;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.jdbc.connection.DataSource;

public class JdbcUtils {

                //非常不解,这一步为什么要在static块前运行!!!
    //初始化的时候应该是静态方法(包括静态块)要在非静态属性前面嘛!
    private  DataSource dataSource = new DataSource();

    private JdbcUtils() {

    }

    private static JdbcUtils instance = new JdbcUtils();

    public static JdbcUtils getInstance() {
        return instance;
    }
    
    static {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public Connection getConnection() throws SQLException {
        Connection conn = dataSource.getConnection();
        return conn;
    }

    public void free(Connection conn, PreparedStatement ps, ResultSet rs) {
        try {
            if (rs != null) {
                rs.close();
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                if (ps != null) {
                    ps.close();
                }
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                if (conn != null) {
                    dataSource.free(conn);
                }
            }
        }
    }
}

这个是自己写的一个DataSource。

package com.jdbc.connection;

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

public class DataSource {
    private Connection conn = null;
    private String url = "jdbc:mysql://localhost:3306/jdbc";
    private String username = "root";
    private String password = "zzx";
    private int maxCount = 5;
    private int currentCount = 0;

    private LinkedList<Connection> connectionPool = new LinkedList<Connection>();
    
    public DataSource(){
        this.createConnection();
    }

    private LinkedList<Connection> createConnection(){
    
        try {
            for(int i=0;i<maxCount;i++){
                conn = DriverManager.getConnection(url, username, password);
                currentCount++;
                connectionPool.addLast(conn);
            }
            return connectionPool;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    public Connection getConnection(){
        if(conn != null){
        conn = connectionPool.removeFirst();
        currentCount--;
        }
        return conn;
    }
    
    public void free(Connection conn){
        if(currentCount < maxCount){
            connectionPool.addLast(conn);
            currentCount++;
        }
    }
}

 下面这个是测试代码

package com.jdbc.test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.jdbc.comm.JdbcUtils;

public class DataSourceTest {

    public static void main(String[] args) throws SQLException{
        
        
        Connection conn = null;
        PreparedStatement ps =null;
        ResultSet rs = null;
        JdbcUtils jdbcUtils = JdbcUtils.getInstance();
        
        for(int i=0;i<10;i++){
            conn = jdbcUtils.getConnection();
            System.out.println(conn);
            
        }
        
    }
}

 这个程序运行出错,我已经知道出错的地方,简单来说就是Class.forName("com.mysql.jdbc.Driver")出现在conn = DriverManager.getConnection(url, username, password)后面,所以抛了异常。我也知道怎么改,但是我非常想不通的一点就是,当条用jdbc的构造函数的时候,为什么不先执行JdbcUtils里的静态块,而是先实例化了DataSource。

     本人很菜,麻烦各位指点一下。


问题补充:
我觉得是这样的
当程序启动的时候 会先将你的static代码块放在内存中一个单独的static区
会并且会先帮你把DataSource 给new出来放在堆内存
当你getInstance的时候其实DataSource对象已经先实例化好了
(因为你用了单例 所以当你通过getInstance加载jdbcutil实例的时候 才会执行static区的代码)

谢谢你的回答,
但是有点搞不懂啊,他放到内存就等于new了一个啦?那么程序的运行顺序就应该改成,非静态属性>静态方法了啊。
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

2条回答 默认 最新

  • 已采纳
    weixin_42514193 小女昆玲 2009-04-05 20:27

    我觉得是这样的
    当程序启动的时候 会先将你的static代码块放在内存中一个单独的static区
    会并且会先帮你把DataSource 给new出来放在堆内存
    当你getInstance的时候其实DataSource对象已经先实例化好了
    (因为你用了单例 所以当你通过getInstance加载jdbcutil实例的时候 才会执行static区的代码)

    点赞 评论 复制链接分享
  • sh66864797 sh66864797 2009-04-07 16:34

    static 在程序加载的时候就加载并且只加载一次的 而data source 是在程序运行时候被实例化的

    点赞 评论 复制链接分享

相关推荐