2010-08-22 101 views
10

如何从枚举构造函数中抛出异常?例如:如何从枚举构造函数中抛出异常?

public enum RLoader { 
    INSTANCE; 
    private RLoader() throws IOException { 
    .... 
    } 
} 

产生错误

未处理的异常类型为IOException

+6

你为什么要这么做?对我来说,这听起来像是滥用枚举概念。枚举值应该是常量,其创建不依赖于任何东西。即使技术上你可以做到这一点(通过抛出未经检查的异常而不是已检查过的异常),我建议你修改你的设计。如果你想通过这个枚举来实现一个Singleton,最好是用普通的类来实现它。 – 2010-08-22 23:33:16

+2

我正在实现一个Singleton,但是如何将它作为一个普通的类手动实现会更好?我仍然必须从静态初始化器调用的代码中引发异常。 您可以从枚举构造函数中抛出未经检查的异常。 – tukushan 2010-08-22 23:53:26

+0

有一些* icky *关于通过访问枚举值来抛出异常。当它是一个单例getInstance()方法时不那么糟糕。 – 2010-08-22 23:55:30

回答

15

因为实例在静态初始化创建,抛出的ExceptionInInitializerError代替。

+5

尽管这是一个可能的解决方案,但我认为这样解决问题并不合理。 – 2010-08-22 23:53:44

0

该方案无法工作。

您正试图从构造函数中抛出一个选中的Exception

该构造函数由INSTANCE enum条目声明调用,因此检查的异常无法正确处理。

另外,在我看来,从构造函数中抛出异常是一种糟糕的风格,因为构造函数通常不应该做任何工作,尤其是不会创建错误。

此外,如果你想抛出一个IOException我假设你想从一个文件初始化某些东西,所以你应该考虑这篇文章dynamic enums

+3

如果从构造函数中抛出异常的风格很糟糕,那么当你的构造函数的参数之一是无效的并且会阻止你的类运行时,你会怎么做?我更喜欢通过抛出异常来快速失败,这样我就可以获得有意义的堆栈跟踪。话虽如此,我同意你的观点,OP不应该试图在**枚举的构造函数中引发异常。 – 2010-08-22 23:57:43

+0

@Kirk Woll:我更喜欢使用确保参数有效性的工厂方法。此外,我主要关注检查异常,RuntimeException将是发送IMO验证错误的更好方式。 – 2010-08-23 00:00:50

+2

对所有对象实例化独家使用工厂方法?哦,可怜的新人**。 :) – 2010-08-23 00:05:45

3

我有一种情况,我想在某些设置类中使用枚举作为键。数据库将存储一个字符串值,允许我们改变枚举常量,而不必去修改数据库(有点难看,我知道)。我想在枚举的构造函数中抛出一个运行时异常作为警告字符串参数长度的一种方法,以避免触碰数据库,然后在我可以轻松检测到它时自动获取约束违规。

public enum GlobalSettingKey { 
    EXAMPLE("example"); 

    private String value; 

    private GlobalSettingKey(String value) { 
     if (value.length() > 200) { 
      throw new IllegalArgumentException("you can't do that"); 
     } 
     this.value = value; 
    } 

    @Override 
    public String toString() { 
     return value; 
    } 
} 

当我为此创建一个快速测试时,发现抛出的异常不是我的,而是一个ExceptionInInitializerError。

也许这是愚蠢的,但我认为这是一个相当有效的方案,想要在静态初始化器中引发异常。

+2

但是原来的异常与ExceptionInInitializerError链接在一起,所以如果你对它调用'getCause()',你会得到原始的异常。 – shrini1000 2012-04-19 06:24:54

相关问题