4

このサイトの別の質問で述べたように、次のようなものは合法ではありません。

public enum MyEnum {
    FOO {
        public Integer doSomething() { return (Integer) super.doSomething(); }
    },
    BAR {
        public String doSomething() { return (String) super.doSomething(); }
    };

    public Object doSomething();
}

これは、明らかに共変の戻り値の型が列挙型定数で機能しないためです (列挙型定数が列挙型のシングルトン サブクラスであるという錯覚を再び打ち破ります...)。

public enum MyEnum2 {
    FOO {
        public Class<Integer> doSomething() { return Integer.class; }
    },
    BAR {
        public Class<String> doSomething() { return String.class; }
    };

    public Class<?> doSomething();
}

ここでは、3 つすべてがオブジェクトを返しClassますが、個々の定数は列挙型全体よりも「より具体的」です...

4

3 に答える 3

4

基本的に、問題は、特定の生成されたサブクラスではなく、コンパイル時の型がMyEnum.FOOisMyEnumであることです。共分散なしでこれを見ることができます:

enum MyEnum {
    FOO {
        public void foo() {}
    };
}

public class Test {
    public static void main(String[] args) throws Exception
    {
        MyEnum.FOO.foo(); // Error
    }
}

基本的に、コンパイラはで宣言されたシグネチャのみMyEnumを認識します。

于 2012-11-10T10:32:07.690 に答える
1

Java 列挙型で Covariant 戻り値の型を使用できますが、通常のクラス階層とは異なり、戻り値が割り当てられる変数にその子型を使用することはできません。

public class EnumCovariance {

   public static void main(String[] args) {
      // Type mismatch: cannot convert from Class<capture#1-of ?> to Class<Integer>
      Class<Integer> something = MyEnum2.FOO.doSomething();
      Child child = new Child();
      Base base = child;
      // ok
      Class<Integer> something3 = child.doSomething();

      // Type mismatch: cannot convert from Class<capture#2-of ?> to Class<Integer>
      Class<Integer> something2 = base.doSomething();
    }
}

abstract class Base {
   public abstract Class<?> doSomething();
}

class Child extends Base {
   @Override
   public Class<Integer> doSomething() {
      return Integer.class;
   }
}

enum MyEnum2 {
   FOO {
      public Class<Integer> doSomething() {
         return Integer.class;
      }
   },
   BAR {
      public Class<String> doSomething() {
         return String.class;
      }
   };

   public abstract Class<?> doSomething();
}
于 2012-11-10T10:48:56.893 に答える
0

このコードはうまく機能します:

public enum MyEnum {
   FOO {
      @Override
      public Integer doSomething() {
         return (Integer)super.doSomething();
      }
   },
   BAR {
      @Override
      public String doSomething() {
         return (String)super.doSomething();
      }
   };

   public Object doSomething() {
      System.err.println( this );
      return null;
   }

   public static void main( String[] args ) {
      MyEnum toto = MyEnum.FOO;
      System.err.println( toto.doSomething() );
   }
}

出力は次のとおりです。

FOO
null

このコードはコンパイルされません。エラーは次"The return type is incompatible with MyEnum2.doSomething()"のとおりです。Cannot cast from Class<Object> to Class<Integer>Cannot cast from Class<Object> to Class<String>

public enum MyEnum2 {
   FOO {
      @Override
      public Class<Integer> doSomething() {
         return (Class<Integer>)super.doSomething();
      }
   },
   BAR {
      @Override
      public Class<String> doSomething() {
         return (Class<String>)super.doSomething();
      }
   };

   public Class<Object> doSomething() {
      System.err.println( this );
      return null;
   }

   public static void main( String[] args ) {
      MyEnum2 toto = MyEnum2.FOO;
      System.err.println( toto.doSomething() );
   }
}
于 2012-11-10T10:38:14.830 に答える