【问题标题】:Is there a particular naming convention for Java methods that throw exceptions?抛出异常的 Java 方法是否有特定的命名约定?
【发布时间】:2010-11-13 05:45:14
【问题描述】:

我很想添加一个像“Ex”这样的后缀来区分抛出异常的方法(具有相似的签名)和不抛出异常的方法。

有这样的约定吗?

【问题讨论】:

  • Spring LDAP 有 4 个不会引发异常的“身份验证”方法。我想添加一个 *do^ 抛出异常的新“身份验证”方法,最好将这些新方法命名为可以将它们与不抛出异常的方法区分开来。
  • 对于忽略异常并继续执行的相反的、尽力而为的方法有一个命名约定:称为 safeClose 的方法即使关闭操作失败也不会抛出 NullPointerExceptions、IOException 或 SQLException。跨度>
  • 我需要从 "authenticate" 方法中捕获 AuthenticationException,以便将失败的原因传递给用户。
  • 我很自豪地宣布 Spring LDAP 开发人员已经实现了我的请求以提供 AuthenticationException。

标签: java coding-style method-names


【解决方案1】:

是的,您将它们命名为与未命名的方法相同。

异常规范还不够吗?

编辑:如果你有类似的 throw/not throw 方法,我推荐Parse/TryParse 模式(Parse 被操作替换)。 .NET Framework 经常使用它(Dictionary<T,K>.TryGetValueMonitor.TryEnterint.TryParse 等)。

编辑:Coding Horror: TryParse and the Exception Tax

【讨论】:

    【解决方案2】:

    不要那样做。

    这就像在问“是否有将两个字符串作为参数的方法的命名约定”。

    Java 已检查异常,这意味着无论如何您都需要声明它们。 所以你可以很容易地看到是否会抛出异常,以及什么类型的异常。 如果不添加异常处理代码,您甚至无法编译调用该方法的代码。

    更新:似乎您的意图是让方法检查某个条件是否为真,但您不想只返回假,而是在不满足条件时抛出异常,这样您还可以传达解释消息(在例外中)。我认为“断言”或“确保”的前缀是有意义的:

     // instead of
     if (! isAuthenticated())
        throw new NotAuthenticatedException("not sure why at this point...");
    
     // you do
     assertAuthentication();
     // which will throw NotAuthenticatedException("proper explanation") inside
    

    【讨论】:

      【解决方案3】:

      为什么要在 Java 中做这样的事情?它已经在语言中内置了异常说明符。编译器会阻止您调用显式抛出异常的方法,而您没有采取一些措施来处理或允许传播异常?

      【讨论】:

        【解决方案4】:

        如果您需要区分这些方法,我相信您可以在 命名 中做到这一点,而无需使用后缀或任何东西,这(正如其他人指出的那样)非常可怕。

        为什么有:

        boolean authenticate(String username, String password);
        

        和(比如说)

        void authenticateEx(String username, String password) throws WhateverException;
        

        当您可以通过传达实际意图使其成为名称中有意义的部分时:

        void ensureCanAuthenticate(String username, String password);
        
        // or
        
        void assertValidCredentials(...);
        
        // or
        
        void authenticateOrDie(...);
        

        ...或任何数量的其他(可能更好的)名称,它们实际上传达了意图,而不是依赖于令人困惑的后缀。

        【讨论】:

          【解决方案5】:

          异常是 Java 中方法签名的一部分,因此这样的命名约定是多余的。

          【讨论】:

            【解决方案6】:

            抛出异常的方法的匈牙利符号?奎尔恐怖!

            您是指已检查或未检查的异常吗?你到底为什么要这么做?

            当您考虑它时,您必须将您的约定添加到每个方法中,因为总是存在潜在的错误或 NPE 或其他可能出错的事情。

            当您检查异常时,“抛出”子句就足够了,并且在上帝的绿色地球上对于未经检查的异常没有好的目的。

            不要这样做。请。

            【讨论】:

              【解决方案7】:

              没有约定,添加 ex 会使这个名字更难读,而且对于普通的 Java 程序员来说很难看。

              但有时我可以想象,将尝试添加到可能引发异常的方法中会使您的代码更容易理解。特别是如果它们未选中。

              它不必像在许多 c/c++ 程序中发现的那样难看,在这些程序中,成员使用 _name 或 mName,整数使用 iValue。 但是在java中也有一些约定。 如果一个方法将返回一个以 is... 为前缀的整数,那么 set、get 和 test 是最常用的示例。所有这些都记录在方法头中,通过返回类型注释等......但是在函数名称中添加一个单词可以更容易和更快地阅读和理解。

              为什么不使用 try 给阅读你代码的程序员一个潜意识的暗示,这个方法很可能会抛出异常。像 tryCopyFile 而不是 tryWriteFile。

              【讨论】:

              • 我认为“try”前缀不太好。对我来说,这似乎暗示着不抛出异常。像 Lock.tryLock() 一样,它会尝试获取锁,但如果不可能,则返回 false。
              【解决方案8】:

              我不知道。

              在我看来,唯一有意义的事情是在单元测试用例中(例如,testFooExpectingException())。但这并不是你真正要谈论的。

              【讨论】:

                【解决方案9】:

                没有这样的约定,因为每个方法都可以抛出异常,无论你是否声明它们。在这个 IDE 工具提示的时代,它也有些多余(当然,除非您没有使用 IDE)。

                我很想知道您为什么会倾向于使用这样的命名约定。

                【讨论】:

                  【解决方案10】:

                  每隔一段时间,您会遇到这样一种情况,即使用像 getSafely() 这样的方法名称可能是有意义的(在实际值无效的情况下返回默认值,对于不太在意实际值与占位符)或其相反的getOrBlowUp()(对于快速失败的代码,其中缺失值在技术上是可能的,但表明应该设置值的代码中存在错误)。

                  但这里的重点不是“方法 2 抛出异常,方法 1 不会”——因为如上所述,任何代码可能抛出 RuntimeException。关键是这两种方法具有不同的错误处理语义,特定于不同的用例,这就是方法名称试图捕捉的内容。

                  即便如此,如果你能摆脱一种或另一种行为,代码通常会更简洁,并调用方法get()

                  这里的一个有用的平行可能是匈牙利符号中的the distinction between Systems Hungarian and Apps Hungarian。 (另请参阅 Joel 关于软件的 this piece on coding conventions。)

                  • Systems Hungarian 只会告诉您变量的类型,因此整数 count 变为 iCount。这是匈牙利符号的最常见形式,恕我直言,它 (1) 对于现代 IDE 来说毫无意义,(2) 如果有人更改类型声明而不重命名变量,则可能具有欺骗性。
                  • Apps Hungarian 告诉您变量的用途,所以表示数据行的整数(或短的、或序号 ID 对象或其他任何东西?)index 表示数据行变为drIndex,表示注释列的index 变为acIndex。这更有用,而且不太可能造成麻烦。

                  调用你的方法 getEx() 是 Systems Hungarian。

                  【讨论】:

                    【解决方案11】:

                    一般不要将其添加到方法名称中。

                    改为添加 throws。

                    int parseInt(String s, int radix) throws NumberFormatException
                    

                    但我个人喜欢 getter,例如

                        getFieldsOrThrow(java.lang.String key)
                        getFieldsOrDefault(java.lang.String key, Value defaultValue)
                    

                    https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/Struct

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2014-08-17
                      • 2019-06-11
                      • 2013-03-11
                      • 2021-08-25
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2018-04-24
                      相关资源
                      最近更新 更多