2011-08-30 4 views
11

だから、私は列挙Javaのパブリック列挙法の目的

public enum Sample { 
    ValueA{ 
     @Override 
    public String getValue(){ return "A"; } 
}, 
ValueB{ 
    @Override 
    public String getValue(){ return "B"; } 

    public void doSomething(){ } 
}; 
abstract public String getValue(); 
}; 

を持っていると私は、列挙型を使用しようとしている他のいくつかのコードを持っています。それが有効である必要がありように思えるが、エラー生成

Sample.ValueB.doSomething(); 

「メソッドdoSomethingの()は、型サンプルについて定義されていません」。これとは対照的に、同じエラーが発生し、妥当と思われる場合には、

Sample value = Sample.ValueB; 
value.doSomething(); 

となります。

私は最初のものがうまくいかない理由について合理的な答えがあり、2つの例がボンネットの中で等価であることに関係します。私は誰かがそれがなぜその方法であるかについてのドキュメンテーションに向けて私を指すことができることを願っていました。

+0

エラーが発生していると言うと本当に助かります... –

+0

'Sample.doSomething()'を呼び出すべきではありませんか? – nfechner

+2

@ nfechner..the doSomething() 'メソッドは静的ではありません.. –

答えて

15

「フィールド」ValueAのタイプはSampleです。つまり、ValueASampleが提供するメソッドのみを呼び出すことができます。 JLS §8.9.1. Enum Constantsから:これらのクラスの体の中で宣言

インスタンスメソッドは、彼らが囲む列挙型でアクセスメソッドをオーバーライドする場合にのみ囲む列挙型の外に呼び出すことができます。さらに重要なこと

:設計の観点からenum値が均一でなければならないいくつかの操作が一つの特定の値で可能である場合(それが実行されている別のコードにつながるかもしれないが)、それは全ての値で可能であるべきです。

10

基本的Sample.ValueBコンパイル時の型値の実行時タイプValueBあろうにもかかわらず、依然としてサンプルです。つまり、コードの2つのスニペットは同等です。クライアントは、にある「余分な」メソッドを見ることができません。のenum値です。

あなたは効果的にこのようにフィールドを宣言として列挙型を考えることができます。

public static final Sample ValueB = new Sample() { 
    @Override 
    public String getValue(){ return "B"; } 

    public void doSomething(){ } 
}; 
4

あなたはSample列挙型、enum Sampleの匿名サブクラスのではなくインスタンスのインスタンスを作成していない

enum Sample 
{ 
    Value{ 
     public void doSomething() 
     { 
       //do something 
     } 
    }; 
} 

を書くとき。 Thetの理由doSomething()は未定義です。

更新:

はあなたがSample$2のインスタンスでメソッドdoSomething()を持っているにもかかわらず、あなたが持っていることを意味し、この

System.out.println(Sample.ValueB.getClass().getName()); 

プリントSample$2

を試してみてください。これは、次のように証明することができますValueBという名前の場合は、タイプSampleのスーパークラスリファレンスを参照しているため、クラスSampleに定義されているメソッドのみがコンパイル時に表示されます。

実行時にdoSomething()と呼ぶことができます。

+1

もっと重要なのは、"フィールド "の型は**まだ' Sample'であり、 'Sample $ 1'ではありません。 –

3

public void doSomething(){ }は、private void doSomething(){ }と同じ効果を持ちます。

doSomething()SampledoSomething()を追加しない限り、ValueBの外側には表示されません。

Sampleの値は、タイプがSampleであるため、異なる値(外部から見た場合)に対して異なるメソッドセットを持つことはできません。

+0

警告: 'Sample' * values * ** do **には、クラス本体がある場合、より具体的な型があります。 'Sample' *フィールド*は' Sample'というタイプしか持っていません。 –

+0

@Joachim:確かですが、これらの特定の型はSampleの匿名サブクラスなので、 "outside"ではSampleで定義されたインタフェースしか使用できません。私は自分自身を明確にしませんでした - 申し訳ありません。 –

関連する問題