无法从枚举转换为它实现的接口

Cannot convert fom enum to interface it implements

我在 Java 7 并且我有以下枚举:

public enum BooleanEnum implements StringRepresentable{
    YES {
        @Override
        public String getStringRepresentation() {
            return "true";
        }
    },
    NO {
        @Override
        public String getStringRepresentation() {
            return "false";
        }
    };
    public abstract String getStringRepresentation();
}

现在我有了方法:

List<StringRepresentable> getValues(){
    return Arrays.asList(BooleanEnum.values()); //Type mismatch: 
                  //cannot convert from List<BooleanEnum> to List<StringRepresentable>
}

这有什么问题enum?它实现了接口,因此代码应该可以正常编译。

如果编译成功,有人可以这样做:

List<StringRepresentation> values = getValues();
values.set(0, new SomeOtherStringRepresentation());

(因为修改 Arrays.asList 返回的列表会修改原始数组),然后您会在 BooleanEnum 的原始数组中存储一个 SomeOtherStringRepresentation!这显然是不允许的。

相反,您可以复制一份,例如 ArrayList:

List<StringRepresentation> getValues(){
    return new ArrayList<StringRepresentation>(Arrays.asList(BooleanEnum.values()));
}

BooleanEnum.values() return 一个 BooleanEnum[],然后 Arrays.asList 你 return 一个 List<BooleanEnum>.

由于 List<BooleanEnum> 不是 List<StringRepresentation> 的子集,因此无法编译此代码。

理论上,您可以通过 returning a List<? extends StringRepresentation> 来编译此代码,但我不建议这样做,因为它对调用方没有多大用处。

你的List的类型是StringRepresentationBooleanEnum只是实现了StringRepresentableinterface不能转换成任何类型class 实现了 interface.

It implements the interface, therefore the code should have compiled fine.

不,因为类型参数被推断为 BooleanEnum - 而 List<BooleanEnum> 不是 List<StringRepresentation>...您可以添加 的实例other StringRepresentation 对后者的实现。

四种可能的选择:

  • 指定您正在 returning StringRepresentation:

    的某个子类的列表
    List<? extends StringRepresentation> get Values() {
        // Implementation as before
    }
    
  • 指定参数类型:

    return Arrays.<StringRepresentation>asList(BooleanEnum.values());
    
  • 为清楚起见,使用中间变量:

    StringRepresentation[] array = BooleanEnum.values();
    return Arrays.asList(array);
    
  • 根本不要 return List<StringRepresentation>; return 一个 Iterable<StringRepresentation>,此时您可以使用 EnumSet 代替:

    Iterable<? extends StringRepresentable> getValues() {
        return EnumSet.allOf(BooleanEnum.class);
    }
    

你应该return像这样:

 return Arrays.<StringRepresentable>asList(BooleanEnum.values());

因为 BooleanEnum 列表与 StringRepresentable 列表不同。