<A> <B> 当 A 从 B 继承时,从枚举集转换为集



标题很好地解释了这个问题。我有一个接口方法:

Set<Field> getFieldSet()

我有一个类,User,看起来像这个

class User {
    enum Fields implements Field {
        USERNAME, PASSWORD;
        ...
    }
    ...
}

现在我想实现UsergetFieldSet()方法。天真的方式似乎只是return EnumSet.allOf(Fields.class),但我得到了以下错误:

> Type mismatch: cannot convert from Set<User.Fields> to Set<Field>

除了手动将EnumSet复制到Set<Field>之外,还有什么好方法可以做到这一点吗?

您可以返回new HashSet<Field>(EnumSet.allOf(Fields.class));

这将绕过这样一个事实,即不能将Set<User.Fields>类型的值分配给Set<Field>类型的变量。

或者,您的接口可以是Set<? extends Field> getFields()可以Set<User.Field>分配给捕获变量。

使用集合.unmoodifiebleSet:

return Collections.<Field>unmodifiableSet(EnumSet.allOf(Fields.class));

优点:

  • 没有不安全的转换强制转换:操作在运行时是类型安全的
  • 返回的集合实际上是Set<Field>,而不是Set<? extends Field>
  • 该集未被复制,仅被包装
  • 返回的集合无法更改

缺点:

  • 返回的集合不能进行变异,但无论如何都不安全
这不起作用的原因是Set<Fields>不是Set<Field>的子类型。例如,如果您从方法返回Set<Fields>,则可能会出现以下情况:
Set<Field> fieldSet = user.getFieldSet(); //Returns an EnumSet<Fields>
fieldSet.add(new Field(){}); //Would compile, but would blow up at runtime, 
                             //because the set can only contain Fields enum 
                             //constants

这里最好的选择是使用不同的集合实现(通常是不可修改的集合(来返回值。例如:

Set<Field> getFieldSet() {
    return Collections.unmodifiableSet(EnumSet.allOf(Fields.class));
}

或者,如果您需要该集是可变的(通常可能不是一个好主意(

Set<Field> getFieldSet() {
    return new HashSet(EnumSet.allOf(Fields.class));
}

我认为这是一个很好的解决方案。这不是你想要的,但距离足够近

import java.util.EnumSet;
import java.util.Set;
public class User {
    enum Fields implements Field {
        USERNAME,
        PASSWORD;
    }
    Set< ? extends Field> getFieldSet() {
        return EnumSet.allOf(Fields.class);
    }
}

相关内容

  • 没有找到相关文章

最新更新