刚才琢磨这个问题主要是在想,如果constructor抛出了exception,那么返回的object是什么一个情况呢?如果我这个object中有一些关键的资源没有初始化,比如说Database connection在创建的时候有可能抛出SQLException,会不会返回一个HALF-MADE的object呢?为了验证,写了如下代码,结论:如果constructor中抛出了exception,constructor不会返回任何object,甚至null也不会返回。(因为程序流程在执行到return之前就跳转到exception处理去了啊亲,当然不会return任何东西!)
class Box { private final int number; public Box(int number) { if (number < 0) { throw new IllegalArgumentException("Negative number: " + number); } this.number = number; } public int getNumber() { return number; } } public class Foo { public static void main(String[] args) { Box box = new Box(999); try { box = new Box(-999); } catch (IllegalArgumentException e) { // ignored } System.out.println(box); } }
回到我刚才遇到的问题,经过这番思考之后,我改写了一下,使用了一个static factory method(当然,针对我这里的情况而言,其实使用constructor也是可以的)
// Data Source public class DatabaseConnection { // data source name private static final String DSNAME = "java:comp/env/jdbc/fooooooooooooo"; private Connection conn = null; private DatabaseConnection(Connection conn) { this.conn = conn; } /** * Construct a new instance of DatabaseConnection. * @return a new instance of DatabaseConnection. * */ public static DatabaseConnection newInstance() throws NamingException, SQLException { Context ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup(DSNAME); Connection conn = ds.getConnection(); return new DatabaseConnection(conn); } public Connection getConnection() { return conn; } public void close() throws SQLException { conn.close(); } }
我搜索了3篇有关constructor的问题,值得一看:
1、Is it good practice to make the constructor throw an exception?
里面讨论了从constructor抛出exception是不是good practice
值得一提的是,里面还讨论了检查argument的正确性应该用exception还是assertion
2、Is doing a lot in constructors bad?
3、How much code should one put in a constructors (Java)?
2和3讨论了constructor应该做哪些工作,不应该做哪些工作,做多少工作合适,以及在什么情况下应该考虑使用Factory或者Builder