Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在例外情况下传达更多信息_Java_Exception - Fatal编程技术网

Java 在例外情况下传达更多信息

Java 在例外情况下传达更多信息,java,exception,Java,Exception,我正在制作一个命令处理库,它接受输入,如果由于各种原因无法执行命令,则抛出异常。我想提供有用的信息给用户什么出了问题,我也希望所有的消息是定制的,以便它可以在多个项目中使用。当我处理用户输入时,有大量的事情可能会出错,对所有这些问题进行异常处理会给我留下比实际命令处理类更多的异常类,因此我提出了一些通用异常:CommandException和CommandUsageException和CommandPermissionException扩展了CommandException 是否值得为所有可能出

我正在制作一个命令处理库,它接受输入,如果由于各种原因无法执行命令,则抛出异常。我想提供有用的信息给用户什么出了问题,我也希望所有的消息是定制的,以便它可以在多个项目中使用。当我处理用户输入时,有大量的事情可能会出错,对所有这些问题进行异常处理会给我留下比实际命令处理类更多的异常类,因此我提出了一些通用异常:
CommandException
CommandUsageException
CommandPermissionException
扩展了
CommandException


是否值得为所有可能出现错误的情况破例,例如
InvalidFlagValueException
ErrorSubcommandArgumentsException
,或者是否有更好的方法?例如,在异常中使用
Enum
来提供更多细节,这是一个好主意吗?

我认为这是一个纯粹的设计决策。您可以映射出您的异常并用它们构建一个继承树。或者,您可以将这些异常分组到广泛的异常中,然后确保该异常具有字符串参数,以便您可以输入消息。如果我是你,我会选择后者,并将消息保存在const final变量中。然后您可以从任何类访问它们,这样您就有了一些一致性。在这种情况下,我还使用了String.format

例如,字符串常量可能是

public static final String CANNOT_READ = "Cannot read string from %s";
然后在解释中做什么

throws new MyException(String.format(CANNOT_READ, "file");

然后,您可以根据调用的类将“file”更改为您想要的任何内容。字符串常量为您提供了一些结构,但提供了一些自定义设置。

以这种方式考虑异常:

  • 您库的用户是否会针对不同的异常执行不同的操作
  • 例如:如果您有函数/方法
    createFile
    ,您可以有不同的异常
    NotEnoughSpace
    NotEnoughPermissions
    FileAlreadyExists
    ——所有这些都需要调用方执行不同的操作,单独捕获它们是有意义的

  • 在您的例子中,您能想象一下
    InvalidFlag
    error子命令的不同处理程序吗?我想这两个都是语法上的致命错误,但是
    CommandPermission
    -有些用户会有,有些没有,抛出它并以不同的方式处理它是有意义的
  • 是否值得为可能出现错误的所有内容(例如InvalidFlagValueException或ErrorSubcommandArgumentsException)设置例外,或者是否有更好的方法

    我回答这个问题的方式是,尝试弄清楚您是否需要单独捕获这些异常;e、 g.您是否编写过明确捕获
    InvalidFlagValueException
    ErrorSubcommandArgumentsException
    的代码

    • 如果确实需要这样做,那么就有理由有单独的例外

    • 如果不需要这样做(只有您可以判断),那么单独的异常类就没有任何优势

    您可能已经发现,通过向异常添加消息字符串、代码和其他信息(并提供getter来检索它们),可以传递额外的信息

    例如,在异常中使用枚举来提供更多细节,这是一个好主意吗

    这很棘手

    • 一方面,
      enum
      是代码编号的干净替代品

    • 另一方面,
      enum
      类型不能动态扩展

    如果您有一个
    enum
    和(比如)10个值,并且希望添加一个11来表示新的错误条件,那么您必须更改源代码并重新编译
    enum
    类。幸运的是,枚举的二进制兼容性规则意味着您可以在不破坏兼容性的情况下添加和/或重新排序值。显然,尽管:

    • 任何使用这些值的代码都需要知道具体的值,如果需要引用新值,则必须重新编译

    • 删除或重命名枚举值将破坏二进制兼容性

    • 现在您有了一个“核心框架”类,随着新命令的添加,该类可能需要更改。如果命令是由第二方和第三方编写的“可插拔”/,则这是一个问题


    但如果这些实际约束是可以接受的,那么使用
    enum
    作为错误代码是一个合理的设计选择。

    我认为“这取决于情况”。尝试一下可能有用,那么我个人会使用至少一些不同的异常类,因为我认为这是一个好的编程,但过度在这里并不是一种美德。这篇优秀的文章(由SO创始人撰写)给出了一个很好的视角:@RobP——这篇文章的要点是:“根本不要抛出异常”。如果你用Java编写代码,这是一个非常极端的观点,我认为这对OP没有帮助。@StephenC我把它的意思理解为“不要将它们用于大量的控制流或例程代码路径,因为它们使调试变得很困难。”。当然,编写Java代码而不抛出任何代码是相当困难的!嗯,这篇文章不是这么说的。它说永远不要抛出异常,并将它们全部转换为返回值。当然,您不应该对正常的流控制使用异常,但这是众所周知的。Joel的观点似乎真的很离谱。在异常中设置一个“变量”数组,该数组包含与异常相关的信息,并提供一条默认消息,最终用户可以在需要时进行检查和替换,并使用变量进行格式化,这是一个好主意吗?几乎像你所做的那样,但在catch上格式化?