《Effective Java》4、通过私有构造器强化不可实例化的能力

it2025-08-29  6

有时候,你可能需要编写只包含静态方法和静态域的类作为工具类,这样的工具类不希望被实例化,实例化对它没有意义。但是在缺少显式构造器的情况下,编译器会提供一个公有的、无参的缺省构造器。

错误做法:做成抽象类强制该类不可被实例化,这是行不通的,该类可以被子类化,且子类也可以被实例化。

解决办法:让这个类包含私有构造器。

//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被子类化,因为所有的构造器都必须是显式或隐式地调用超类的构造器,此时就没有可以访问的超类构造器了;

最新回复(0)