- 有时候,你可能需要编写只包含静态方法和静态域的类作为工具类,这样的工具类不希望被实例化,实例化对它没有意义。
- 但是在缺少显式构造器的情况下,编译器会提供一个公有的、无参的缺省构造器。
错误做法:做成抽象类强制该类不可被实例化,这是行不通的,该类可以被子类化,且子类也可以被实例化。
解决办法:让这个类包含私有构造器。
//Noninstantiable utility class
public class JDBCUtil {
//Suppress default constructor for noninstantiability
private JDBCUtil() {
throw new AssertionError();
}
/**获取连接*/
public static Connection getConnection() {
Connection conn = null;
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/flowersale";
String username = "root";
String password = "root";
conn = DriverManager.getConnection(url, username, password);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
/**
* 释放资源
* @param rs
* @param stmt
* @param conn
*/
public static void release(ResultSet rs,Statement stmt,Connection conn) {
if(rs!=null) {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(stmt!=null) {
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 增删改代码整合
*/
public static int execute(String sql,Object... args) {
int result = -1;
Connection conn = null;
PreparedStatement ps = null;
try {
conn = JDBCUtil.getConnection();
ps = conn.prepareStatement(sql);
for(int i=0;i<args.length;i++) {
ps.setObject(i+1, args[i]);
}
result = ps.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
JDBCUtil.release(null, ps, conn);
}
return result;
}
}
上述代码是一个简单的JDBC连接数据库的工具类,在调用的过程中完全没必要实例化,因此把该类的构造函数私有化;
缺点:使得一个类不能1被子类化,因为所有的构造器都必须是显式或隐式地调用超类的构造器,此时就没有可以访问的超类构造器了;