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();
}

在这里,所有三个返回Class对象,但单个常量比整个枚举类型“更具体”......

4

3 回答 3

4

从根本上说,问题在于 is 的编译时类型,MyEnum.FOO不是特定生成的子类。您可以在没有任何协方差的情况下看到这一点:MyEnum

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 枚举中使用协变返回类型,但我们不能使用该子类型作为返回分配给的变量,这与普通类层次结构不同。

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 回答