使java代码健壮但不混乱所需的异常量

使java代码健壮但不混乱所需的异常量,java,exception,Java,Exception,最近,我对我的一些java类有点偏执,我一直在尽可能地插入异常,以确保我没有将值设置为null,或者在没有正确初始化的情况下获取值。起初,遵循标准验证模式,这似乎是一个好主意: public method doSomething(arg1) { if(!isValidArg1(arg1)) { throw new IllegalArgumentException; } ... } 但现在我的每一个getter/setter都是这样的: publ

最近,我对我的一些java类有点偏执,我一直在尽可能地插入异常,以确保我没有将值设置为null,或者在没有正确初始化的情况下获取值。起初,遵循标准验证模式,这似乎是一个好主意:

public method doSomething(arg1)
{
    if(!isValidArg1(arg1))
    {
        throw new IllegalArgumentException;
    }

    ...
}
但现在我的每一个getter/setter都是这样的:

public String getLogicalName()
{
    if (logicalName == null)
    {
        throw new UninitializedAttributeException("attribute: logical name.");
    }

    return logicalName;
}

public void setLogicalName(String logicalName)
{
    if (StringUtils.isBlank(logicalName))
    {
        throw new IllegalArgumentException("attribute: logical name, illegal value: null, empty or whitespace.");
    }

    this.logicalName = logicalName;
}
除了在编写这些琐碎的方法上浪费太多时间外,我觉得自己设计过度了。当然,调试会变得更加严格,但它不像普通的nullpointerexpection那样不会告诉您问题所在

我抛出所有这些异常的主要原因是,我想向前端的最终用户提供一条关于出错原因的清晰信息。我对一些程序感到失望,这些程序只是
catch(Exception e)
围绕着他们所有的代码,如果某个地方出了问题,用户看到的只是“某个地方出了问题,但我不能告诉你什么和在哪里。”。然而,大多数情况下,用户无法对这些异常采取任何措施,因为这是一个开发问题(尽管用户可以准确地告诉开发人员出了什么问题,这很好…)。这是不是设计过度了


我对此表示怀疑。其他开发人员如何应对这种情况?在哪些情况下,显式检查方法的输入/输出值是一种好的做法?在哪些情况下,方法的输入/输出值冗余且使源代码混乱?可以画一条线吗?

输入验证始终是一个好主意-越早完成越好。我建议对所有非私有方法都这样做。有些人甚至主张对私有方法也这样做,以防可见性随时发生变化。其他人信任自己的包,只验证公共和受保护的方法

不需要在getter中执行验证。您可以完全控制类的内容,因此字段不应进入错误状态。输入验证确保您永远不会设置以后在getter中不批准的状态值。记住从getter返回可变对象时的防御性复制

关于用户的错误消息——只需关注抛出对您的方法有意义的异常即可。以后如何向用户显示这些内容取决于表示层。你所能做的就是在课堂上准确地描述出哪里出了问题

相关阅读:
  • “第61项-抛出适用于抽象的异常”,(有效Java,第二版)


如果您对这些检查的设计方面感兴趣,Microsoft有一个有趣的C#系统,它允许您定义方法的输入要求以及可以作为输出返回的内容。它比运行时检查更进一步,因为它需要与静态分析工具相结合

代码合同

我试着在Java中寻找类似的东西。如果您想立即使用某些东西,这可能会很有趣:

番石榴图书馆:预处理


另外,请注意“最终用户”!=“最终用户”。作为您的类的“最终用户”的程序员可能会遇到简短但完整的信息。只有应用程序前面的“最终用户”才会被宠爱。我不确定是否有必要检查getters。在我的例子中,我使用的bean中的字段都是标准的null(也就是说,它们没有在构造函数中设置为某个值)。如果我在字段设置为有意义的内容之前错误地获取了它,我很可能会在某个地方得到一个空指针。如果我像上面代码中那样抛出“uninitializedException”,我会立即知道我试图访问哪个字段,并且在初始化它之前访问它是错误的。我的想法错了吗?@user1884155这可能是一个有效的用例。你可以把AspectJ看作是一种在不干扰你的bean的情况下添加健全性检查的方法。感谢有用的见解,但是我并没有寻找验证的方法,我希望在使用验证时是明智的检查。(凌乱了源代码/降低了程序的运行速度,没有实际收益)这可能是一个很好的问题