我正面临一个用例,我想声明一个带有初始化语句的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); } }
因为静态块确实非常难以阅读。有没有人建议如何以一种漂亮,干净的方式处理这种情况?
答案 0 :(得分:47)
如果您不喜欢静态块(有些人不喜欢),那么另一种方法是使用静态方法。 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
。)
答案 1 :(得分:16)
您的代码完全有效。我觉得很难读。其他方式只会使情况变得更糟。对于初学者来说,他们只是难以阅读,因为大多数人都不熟悉。关于代码中元素的排序,请遵循标准约定。例如。不要将静态初始化器放在代码的中间或整个底部,也不要将多个静态初始化器分布在类中。在静态声明之后,只需将其置于顶部。
答案 2 :(得分:5)
static
块不难阅读。所以我建议这个解决方案。
但是,您可以将对象包装在另一个对象中
ObjectNameWrapper
与您的interface
共享ObjectName
,其构造函数调用您的ObjectName
构造函数,隐藏所有已检查的异常。但同样,我会选择静态选项。
答案 3 :(得分:2)
您可以使用带有龙目岛@SneakyThrows
注释的方法
public static final ObjectName OBJECT_NAME = createObjectName();
@SneakyThrows(SomeException.class)
private static ObjectName createObjectName() {
return new ObjectName("foo:type=bar");
}
此注释使受检查的异常的行为类似于未受检查的异常。