2009-12-08 38 views
31

我面临一个使用情况下,我想声明static final场与被声明为抛出checked异常的初始化语句静态最终字段初始值。通常情况下,它会是这样的:如何处理抛出的checked exception

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

我这里的是,ObjectName构造函数可能会抛出各种检查异常,我不关心这个问题(因为我知道我的名字是有效的,如果它不幸发生崩溃,那么它是没问题的)。 Java编译器不会让我忽略这一点(因为它是一个checked exception)时,我宁愿不诉诸:

 
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

我个人的解决方案是抛出'CheckedExceptionsAreAPainInTheAssSometimesException',这是一个运行时异常。该程序将只会崩溃。 – Airhead 2017-10-18 01:34:22

回答

40

如果你不喜欢静态块(有的人不),那么还有一个办法是使用静态方法。 IIRC,乔希布洛赫推荐这个(显然不是在快速检查的有效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

我没想到这件事,尽管现在我读它,我敢肯定100%,我很久以前使用这种方法。我会使用它,因为我不喜欢静态块,也喜欢我的代码可以被初学者阅读(你永远不知道谁会自己维护你的代码:))。 – Romain 2009-12-08 14:17:54

+0

给我一个编译器错误“必须返回一个ObjectName类型的结果” - 一个简单的解决方案是在'catch'块中有'return null'吗?但后来有点奇怪调试 – mmcrae 2014-11-12 22:54:47

+0

我认为你指的是项目59:避免不必要地使用检查的异常(Effective Java,2nd Edition)。在那篇文章中,Bloch建议代码的作者引发一个异常,以考虑它的客户是否可以在遇到异常时采取一些有用的行动。这不同于这种情况,问题不是抛出异常的合法性,而是如何最好地处理异常。从查看'java.lang.Error'的文档,我发现抛出一个错误的感觉并不是这里要做的最好的事情。 – nullstellensatz 2015-09-19 16:45:13

5

static块并不难读。所以我会推荐这个解决方案。 但是,你可以用你的对象在另一个对象,例如 ObjectNameWrapper这股的interfaceObjectName,且其构造函数调用您的ObjectName构造函数,隐藏所有检查发生的异常。但是,我再次选择静态选项。

+2

引入另一个对象似乎很钝。 – 2009-12-08 13:21:27

+1

我当然同意你的看法。你的静态方法建议更好。 – Bozho 2009-12-08 13:35:37

16

你的代码是完全有效的。我不觉得难以阅读。其他方式只会使情况更糟。他们对于初学者来说只是难以阅读,因为他们中的大多数人都不熟悉这一点。只需遵循关于代码中元素排序的标准约定。例如。不要在代码的中间或整个底部放置静态初始化器,也不要在整个类中传播多个静态初始化器。在静态声明之后,只需在顶部放一个。

+0

这是一个非常有效的点(所以我投它虽然不接受的话),蚂蚁GPP也是最好的说明。我不会使用这种方法,因为正如你所说,这对于初学者来说只是难以理解/阅读的......而且我无法确保在我之后维持它的人会有经验:)。 – Romain 2009-12-08 14:20:44

+0

我不确定我是否愿意。通过将其重构为“私有静态”方法,您可能会失去监督权。通常的做法是将这些方法(效用方法)放在整个课堂的底部。但是,好的,现在你有IDE,这样你就可以点击前进。 – BalusC 2009-12-08 14:33:13

相关问题