IllegalStateException 是否适用于不可变对象?
不,因为不可变对象只有一种状态,不能从一种合法状态转移到另一种合法状态。
所以,你正在构造一个不可变对象,你的对象应该有一个 max 方法
class YourObject {
public BigInteger max(){ ... }
}
我这种情况IllegalAgumentException应该是正确的,但不是直到方法执行完毕,而是对象创建时!
因此,在这种情况下,如果您有一个不可变的大整数集合,并且使用零元素创建它,那么您在创建集合时会收到“无效参数”,这时您必须抛出异常。
我同意 Jon 的观点,如果您的用例或在您的分析中,您愿意支持其余的操作,您可以抛出 NoSuchElementException,但我认为这将推迟问题。最好首先避免创建对象。
所以,抛出 IllegalArgumentException 就像:
// this is my immutable object class
final class YourObject {
private final Collection<BigInteger> c;
public YourObject( BigInteger ... values ) {
if( values.length == 0 ) {
throw new IllegalAgumentException("Must specify at least one value");
}
... initialize the rest...
}
public BigInteger max() {
// find and return the max will always work
}
}
客户:
YourObject o = new YourObject(); // throws IllegalArgumentException
// the rest is not executed....
doSomething( o ) ;
...
doSomething( YourObject o ) {
BigInteger maximum = o.max();
}
在这种情况下,您不需要检查 doSomething 中的任何内容,因为程序会在创建实例时失败,而这又会在开发时修复。
抛出 NoSuchElementException 会像:
final class YourObject {
private final Collection<BigInteger> c;
public YourObject( BigInteger ... values ) {
// not validating the input :-/ oh oh..
... initialize the rest...
}
public BigInteger max() {
if( c.isEmpty() ) { throw NoSuchElementException(); }
// find and return the max will always work after this line
}
}
客户:
YourObject o = new YourObject(); // it says nothing
doSomething( o ) ;
...
doSomething( YourObject o ) {
BigInteger maximum = o.max();// ooops!, why? what?...
// your object client will start questioning what did I do wrong
// and chais of if( o != null && o.isEmpty() || moonPhaseIs... )
}
请记住,如果程序失败,您能做的最好的事情是to making it fail fast。
Collections.max 有不同的目的,因为作为一个实用方法(不是不可变对象),他不能对空集合的创建负责(发生这种情况时他不在场),他唯一能做的就是说 “这个集合中没有 max 这样的东西” 因此 NoSuchElementException。
最后一点,RuntimeExceptions,should be used for programming mistakes only(可以通过在发布之前测试应用程序来修复)