代码之家  ›  专栏  ›  技术社区  ›  Romain

如何处理引发选中异常的静态最终字段初始值设定项

  •  35
  • Romain  · 技术社区  · 16 年前

    我面临一个用例,我想声明一个 static final 具有声明为引发已检查异常的初始值设定项语句的字段。通常,它看起来是这样的:

    public static final ObjectName OBJECT_NAME = new ObjectName("foo:type=bar");
    

    ObjectName 构造函数可能会抛出各种检查过的异常,我并不关心这些异常(因为我知道我的名字是有效的,如果它不是有效的话,如果它严重崩溃也没关系)。java编译器不会让我忽略这一点(因为这是一个已检查的异常),我不想求助于:

    public static final ObjectName OBJECT_NAME;
    static {
        try {
            OBJECT_NAME = new ObjectName("foo:type=bar");
        } catch (final Exception ex) {
            throw new RuntimeException("Failed to create ObjectName instance in static block.", ex);
        }
    }
    

    因为静态块非常非常难以读取。有人对如何以一种好的、干净的方式处理这个案件有什么建议吗?

    3 回复  |  直到 5 年前
        1
  •  52
  •   Tom Hawtin - tackline    10 年前

    如果您不喜欢静态块(有些人不喜欢),那么另一种方法是使用静态方法。IIRC,Josh Bloch推荐了这一点(显然不是在快速检查的有效Java中)。

    public static final ObjectName OBJECT_NAME = createObjectName("foo:type=bar");
    
    private static ObjectName createObjectName(final String name) {
        try {
            return new ObjectName(name);
        } catch (final SomeException exc) {
            throw new Error(exc);
        }  
    }
    

    或:

    public static final ObjectName OBJECT_NAME = createObjectName();
    
    private static ObjectName createObjectName() {
        try {
            return new ObjectName("foo:type=bar");
        } catch (final SomeException exc) {
            throw new Error(exc);
        }  
    }
    

    (已编辑:更正了第二个示例,使其从方法返回,而不是指定 static

        2
  •  18
  •   BalusC    16 年前

    你的代码完全有效。我觉得阅读并不困难。其他方法只会让事情变得更糟。他们只是刚开始读起来很难,因为他们中的大多数人都不熟悉这一点。只需遵循有关代码中元素顺序的标准约定即可。例如,不要将静态初始值设定项放在代码的一半或整个底部,也不要将多个初始值设定项分散在类中。在静态声明之后,只需在顶部放置一个。

        3
  •  5
  •   Bozho    16 年前

    static 块并不难读。所以我推荐这个解决方案。 ObjectNameWrapper 共享一个 interface 用你的 ObjectName ,以及谁的构造函数调用 对象名

        4
  •  2
  •   mturina    5 年前

    可以使用带有Lombok注释的方法 @SneakyThrows

    public static final ObjectName OBJECT_NAME = createObjectName();
    
    @SneakyThrows(SomeException.class)
    private static ObjectName createObjectName() {
        return new ObjectName("foo:type=bar");
    }