2011-03-05 92 views
10

读取SCJP的书,我发现这样的事情在第1章“自检”:的Java:访问常量枚举(ENUM)

enum Animals { 
    DOG("woof"), CAT("meow"), FISH("burble"); 
    String sound; 
    Animals(String s) { sound = s; } 
} 

class TestEnum {  
    static Animals a; 
    public static void main(String[] args) {                      
     System.out.println(a.DOG.sound + " " + a.FISH.sound); 

     // the following line is from me 
     System.out.println(Animals.DOG.sound + " " + Animals.FISH.sound); 
    } 
} 

注:该代码编译罚款。 我不明白的是为什么我们可以从变量a访问DOG,CAT或FISH常量。我认为DOG,FISH和CAT常量的实现方式类似于public static final Animals DOG = new Animals(1); 因此如果它们真的是静态的,我们为什么可以从a访问它们? 最后一行是我熟悉的方式。

回答

3

写作a.DOG与写作Animal.DOG相同。也就是说,编译器会用它的编译时间类型Animal替换变量。它被认为是不好的代码,因为它隐藏了它依赖于编译时类型而不是动态类型a的事实。

+0

'a.DOG'与动物狗不同,'a'一定不能为空。 – bestsss 2011-03-05 21:05:27

+3

@bestsss枚举值是静态的,所以它不依赖于a的值,运行它与一个== null工作得很好。 – josefx 2011-03-05 21:36:41

1

可以从一个实例访问静态,但它真的很糟糕的味道,因为静态没有绑定到一个实例绑定到类。

无论这本书说什么,不要使用这种方式的静态。如果你运行checkstyle之类的,他们也会发出警告:)

在你的例子中,BTW a为null。它是否在某处被初始化?

编辑

我知道编译器知道什么a.DOG结合了,因为静不能被重写。它不需要a来确定调用,只有编译时的类型a,它具有。

我也知道这个例子虽然anull(我试过让我知道:)。

但我仍然认为这很奇怪,你可以从null得到的东西。而且它的困惑:

Animals a = null; 
System.out.println(a.DOG); // OK 
a.doSomething(); // NullPointerException 

当我将调试NPE我会假设,一个不能为空的的println工作的罚款。混乱。

啊,Java。如果你认为你已经看到了这一切,你又得到了别的东西:)

+0

因为代码访问一个静态字段,它使用的是对象引用的类型而不是实例的值,所以它无关紧要,它是空的。这是这个例子怪异的一部分。 – 2011-03-05 20:42:24

+0

这本书不会说这样的代码。这只是第一章结尾处的一个问题,我回答了错误的原因,我不知道我们可以使用a.SOMETHING。我明白这是不好的实践。 – florian 2011-03-05 20:53:44

+0

@florian对我来说,你可以从_null_ _a_中得到某些东西令人困惑 – extraneon 2011-03-05 21:03:16

5

虽然这可行,不要这样做。使用枚举Animal.DOG,Animal.CAT

以上做的是声明一个枚举类型的对象,并引用其上的静态DOG。编译器知道a的类型,并知道你想要Animal.DOG。但是这会杀死可读性。

我相信这样做的目的是为了缩短枚举的用法。 a.DOG而不是Animal.DOG。如果你真的想缩短它,你可以使用import static fqn.of.Animal,然后简单地使用DOG

+0

或者目的是你没有得到你的Java认证... :-( – florian 2011-03-05 20:57:35

+0

+1为_import static_出于某种原因,我只用它在junit测试(导入静态junit.assertEquals或模拟),但它会工作与枚举也:) – extraneon 2011-03-05 21:05:07

+0

@ xtraneon - 我也是。即使在测试中,我也倾向于避免静态导入。但无论如何,这是更短代码的官方选择。没有丑陋的黑客。 – Bozho 2011-03-05 21:17:31