【发布时间】:2010-03-05 18:47:48
【问题描述】:
假设有这种不可变的记录类型:
public class Record
{
public Record(int x, int y) {
Validator.ValidateX(x);
Validator.ValidateY(y);
X=x;
Y=y;
}
public final int X;
public final int Y;
public static class Validator {
public void ValidateX(int x) { if(x < 0) { throw new UnCheckedException; } }
public void ValidateY(int y) { if(y < 0) { throw new UnCheckedException; } }
}
}
请注意,它会引发未经检查的异常。原因是这是一个经常使用的对象,并且必须处理已检查的异常很不方便。
但是,如果此对象位于类库中,则它可用于验证用户输入(或其他一些外部输入)。现在它开始听起来应该是一个 CHECKED 异常,因为输入不再取决于程序员。
大家想好了吗?我应该勾选还是不勾选,还是有更好的设计?
更新:
我的困惑来自这个场景:通常记录会这样使用:
Record r = new Record(1,2);
OtherObj o = new OtherObj(r);
这取决于程序员,所以未经检查的异常是可以的。
但是,当您从用户那里获取 Record 参数时,您想验证它们对吗?所以你可以打电话给
Record.ValidateX(inputX);
Record.ValidateY(inputY);
因为输入不再受控制,它可能会抛出已检查异常?
抱歉,我通常不会太在意这个(我个人认为未选中就可以了)。但这实际上是家庭作业中的一个问题,我想把它做好,哈哈。
更新(2): 我开始认为我需要的是 ValidateX 抛出一个检查异常,因为如果涉及用户输入,通常会使用它。在这种情况下,我们可以再次要求用户输入。但是,对于 Record 构造函数,它将抛出已检查的异常,因为构造带有无效参数的 Record 是违反 API 的。新代码如下所示:
public class Record
{
public Record(int x, int y) {
try
{
Validator.ValidateX(x);
Validator.ValidateY(y);
}catch(CheckedException xcpt) { throw new UnCheckedException(xcpt.getMessage()); }
X=x;
Y=y;
}
public final int X;
public final int Y;
public static class Validator {
public void ValidateX(int x) throws CheckedException { if(x < 0) { throw new CheckedException; } }
public void ValidateY(int y) throws CheckedException { if(y < 0) { throw new CheckedException; } }
}
}
现在程序员可以在将参数传递给 Record 类之前验证参数。如果没有,那么它就是一个 API 违规,并抛出一个未经检查的异常。
这听起来怎么样?!
【问题讨论】:
-
这 真的 是一个 Validator 类,还是 SO 的示例只是这样表述的?如果它实际上是一个验证器,那么我希望它通过其正常的 isValid/isNotValid 方法简单地指示无效输入。 EG:如果你的 'x' 是 Integer,那么即使 null 也不应该抛出任何东西,仅仅表明传递的值是无效的。
-
Validate[XY] 的目的是告诉您所提供的值是否合适,或者这只是不幸的命名?更具体地说,Validate[XY] 的文档对有效输入值和提供无效输入的后果有什么看法?如果它说当你传入一个