2012-04-28 43 views
2

我刚刚注意到一个奇怪的情况,并想看看是否有人能够解释它。这里是我的情况:在枚举上使用开关时出现奇怪的编译错误

private enum Classifiers { 
    NEURAL_NETWORK, NEAREST_NEIGHBOURS, IDENTITY; 
} 
private ClassifierInterface getClassifierInstance(Classifiers classifier) { 
    switch (classifier) { 
    case NEURAL_NETWORK: 
     return new DoubleLayeredNeuralNetwork(); 
    case NEAREST_NEIGHBOURS: 
     return new NearestNeighbours(); 
    case IDENTITY: 
     return new IdentityClassifier(); 
    } 
    return null; // If I comment out this line I get compilation error 
} 

请参阅评论。我预计此行会报告Unreachable code错误。相反,如果我注释掉这一行,我会得到Method must return value错误。但是,程序流程无法通过那里。

我甚至认为这将成为null值传入的情况下的警戒情况,但如预期的那样,这为交换机条件触发NullPointerException

我不经常使用switch,可能我在这里错过了一些东西。有人可以尝试帮助理解这种行为吗?

+0

我一直想知道为什么过编译器是不是足够聪明地看到,它总是返回的东西和'返回空'是多余的。 – 2012-04-28 07:45:15

回答

4

这是正确的行为,因为您没有默认的case语句。问题是您可以稍后将值添加到enum,而不是重新编译使用它的代码。通过强制你在不是其中一个价值的时候处理它,这是被覆盖的。

BTW:classifier可能为空,这是另一个选项开关不幸的处理。

+0

感谢您的回答。然而,你的顺便说一句不是不太如此,我已经提到它在我的问题:空值触发交换机中的NPE。 – 2012-04-28 07:50:35

+0

我的观点是,我希望切换到支持'case null:'或将'null'作为'default':' – 2012-04-28 07:55:15

+0

对不起,我误解了你。 – 2012-04-28 07:55:49

3

这个问题很有趣...

我们有这样的事情,编译器是幸福的!

Java的Languaje规格说:

一个Java编译器被鼓励(但不是必需的),以提供一个警告 如果上一个枚举值表达式的开关缺少默认标签和 缺乏一个或多个枚举类型的常量的情况标签。 (这种 声明会默默地做什么,如果表达式的值为缺失的常量 之一。)

+0

谢谢你的回答。特别是对于报价。但是,在那里提到了一个警告,同时我收到编译错误。有趣。你的例子也不错。 – 2012-04-28 07:52:43