标题很好地解释了这个问题。我有一个接口方法:
Set<Field> getFieldSet()
我有一个类,User
,看起来像这个
class User {
enum Fields implements Field {
USERNAME, PASSWORD;
...
}
...
}
现在我想实现User
的getFieldSet()
方法。天真的方式似乎只是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);
}
}