48

我正面临一个用例,我想声明一个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);
    }
}

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

4

4 回答 4

53

如果您不喜欢静态块(有些人不喜欢),那么另一种选择是使用静态方法。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。)

于 2009-12-08T13:20:56.820 回答
18

您的代码完全有效。我觉得读起来不难。其他方式只会让事情变得更糟。它们只是初学者难以阅读,因为他们中的大多数人对此并不熟悉。只需遵循关于代码中元素排序的标准约定。例如,不要将静态初始化器放在代码的中途或整个底部,也不要让它们中的多个散布在类中。只需将一个放在顶部,在静态声明之后。

于 2009-12-08T12:54:57.017 回答
5

static块不难阅读。所以我推荐这个解决方案。但是,您可以将您的对象包装在另一个对象中,例如 ,它与您的ObjectNameWrapper共享一个,并且其构造函数调用您的构造函数,从而隐藏所有发生的检查异常。但同样,我会选择静态选项。interfaceObjectNameObjectName

于 2009-12-08T12:54:15.920 回答
3

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

public static final ObjectName OBJECT_NAME = createObjectName();

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

此注释使已检查的异常表现得像未检查的异常。

于 2020-09-12T16:02:03.890 回答