Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 对实现相同接口的枚举类集合使用泛型_Java_Generics_Enums_Guava - Fatal编程技术网

Java 对实现相同接口的枚举类集合使用泛型

Java 对实现相同接口的枚举类集合使用泛型,java,generics,enums,guava,Java,Generics,Enums,Guava,我试图通过使用Guava的迭代遍历类的列表来实现相同字段接口的几个枚举类: 搜索名称的字段值=null; 对于(最终类>类别:ImmutableList.of)( EntityField.class, AddressField.class, PersonFunctionType.class){ valueOfSearchName=Fields.valueOfSearchName(clazz,term.field());//错误 if(valueOfSearchName!=null){ //做点什

我试图通过使用Guava的迭代遍历
的列表来实现相同
字段
接口的几个枚举类:

搜索名称的字段值=null;
对于(最终类>类别:ImmutableList.of)(
EntityField.class,
AddressField.class,
PersonFunctionType.class){
valueOfSearchName=Fields.valueOfSearchName(clazz,term.field());//错误
if(valueOfSearchName!=null){
//做点什么。。。
打破
}
}
我不想在所有枚举类中重复相同的代码(用于建立索引和查找),因此我使用helper静态类
字段
包含
字段。valueOfSearchName
方法:

searchname的公共静态字段值( 最终类clazz,最终字符串searchName){ //TODO:缓存索引 最终不可变映射索引=Maps.uniqueIndex( allOf(clazz),GET_SEARCH_NAME_函数); 返回index.get(searchName); } 不幸的是,Eclipse显示了一个错误:

Bound mismatch: 
The generic method valueOfSearchName(Class<E>, String) of type Fields is not 
applicable for the arguments (Class<capture#1-of ? extends Enum<?>>, String).
The inferred type capture#1-of ? extends Enum<?> is not a valid substitute
for the bounded parameter <E extends Enum<E> & Field>
绑定不匹配:
类型字段的泛型方法valueOfSearchName(类,字符串)无效
适用于参数(类考虑
Class
Class
有两个通配符,而
Class
只有泛型参数。前者将允许
Class
。因此,如果不对枚举做额外的特殊操作,则类型不兼容

如何修复?一个额外的间接层

public final class MetaEnum<E extends Enum<E>> {
    private final E clazz;
    public static <E extends Enum<E>> MetaEnum<E> of(E clazz) {
        return clazz;
    }
    private MetaEnum(E clazz) {
        this.clazz = clazz;
    }
    public E clazz() {
        return clazz;
    }
    // ...
}

for (final MetaEnum<?> meta : ImmutableList.of(
    MetaEnum.of(EntityField       .class),
    MetaEnum.of(AddressField      .class),
    MetaEnum.of(PersonFunctionType.class)
)) {
    Field valueOfSearchName = Fields.valueOfSearchName(
        meta.clazz(), term.field()
    );
    ...
公共最终类元枚举{
私人期末电子课堂;
(E clazz)的公共静态元枚举{
回击声;
}
私有元枚举(E clazz){
this.clazz=clazz;
}
公共E clazz(){
回击声;
}
// ...
}
for(final MetaEnum meta:ImmutableList.of(
元枚举(EntityField.class),
元枚举(AddressField.class),
元枚举(PersonFunctionType.class)
)) {
Field valueOfSearchName=Fields.valueOfSearchName(
meta.clazz(),term.field()
);
...

(通常的堆栈溢出dislaimer:与其说是尝试编译,不如说是尝试编译。)

可能是这样的:

import java.util.*;
class N {
    static int n;
}
interface HasField {
    int getField();
}
enum Color implements HasField {
    r, g, b;
    public int getField() {
        return field;
    }
    private int field = N.n++;
}
enum Day implements HasField {
    m, t, w, th, f, sa, su;
    public int getField() {
        return field;
    }
    private int field = N.n++;
}
    class Helper {
    Helper(Set<HasField> set) {
        for (HasField hasField : set)
            if (hasField instanceof Enum) {
                Enum<?> e = (Enum<?>) hasField;
                for (Object o : e.getDeclaringClass().getEnumConstants()) {
                    map.put(((HasField) o).getField(), (Enum<?>) o);
                }
            } else
                throw new RuntimeException(hasField + " is not an enum!");
    }
    final Map<Integer, Enum<?>> map = new TreeMap<Integer, Enum<?>>();
}
public class Main {
    public static void main(String[] args) {
        Set<HasField> set = new LinkedHashSet<HasField>();
        set.add(Color.r);
        set.add(Day.m);
        Helper helper = new Helper(set);
        for (int i = 0; i < N.n; i++)
            System.out.println(i + " " + helper.map.get(i));
    }
}
import java.util.*;
N类{
静态int n;
}
接口哈斯菲尔德{
int getField();
}
枚举颜色字段{
r、 g,b;
公共int getField(){
返回字段;
}
私有int字段=N.N++;
}
枚举日期字段{
m、 t,w,th,f,sa,su;
公共int getField(){
返回字段;
}
私有int字段=N.N++;
}
类助手{
助手(集合){
for(HasField HasField:set)
if(枚举的hasField实例){
枚举e=(枚举)hasField;
对于(对象o:e.getDeclaringClass().getEnumConstants()){
map.put(((HasField)o.getField(),(Enum)o);
}
}否则
抛出新的RuntimeException(hasField+“不是枚举!”);
}
最终地图>();
}
公共班机{
公共静态void main(字符串[]args){
Set Set=newlinkedhashset();
集合。添加(颜色r);
集合。添加(第m天);
助手=新助手(集合);
对于(int i=0;i
灵感来源于我创建的包装类,它包含
es,但只包含那些带有签名的

生成编译错误


此外,
valueOfSearchName
现在是
FieldEnumWrapper
的方法,帮助类更有意义。

此链接可能会有所帮助,Eclipse以不同意常识而闻名。请查看此帖子:@baba I不能替换
通配符,在for each循环中使用命名类型参数
t
lem发生…但是我将(@SuppressWarnings(“rawtypes”)的循环更改为
最后一节课:…
它成功了……这是正确的方法吗?好吧,我想这是其中一种方法。至少对我来说,你的代码很难像现在这样一眼就能看懂。然而,另一种方法是完全反射器,去掉你的助手类,在我看来,它就像一个si的样板简单任务。@baba
valueOfSearchName
进入了新的
FieldEnumWrapper
类,该类确保enum实现
Field
接口并对所有这些类执行适当的魔法,请参见我自己的答案;)创建元素集而不是类和
e的组合。getDeclaringClass().getEnumConstants()
以及
Enum HasField
强制转换都是不可读的,也不是类型安全的…还有
set.add(new HasField(){public int getField(){return 42;}});
是一个运行时类castexception。添加了一个测试:HasField instanceof Enum仍然,我更喜欢编译时异常,而不是运行时;)同意。但是我的仿制药有点弱。也许其他人可以解决它。
public final static class FieldEnumWrapper<E extends Enum<E> & Field> {
  private final Class<E> clazz;
  private final ImmutableMap<String, E> index;

  public static <E extends Enum<E> & Field> 
      FieldEnumWrapper<E> of(final Class<E> clazz) {
    return new FieldEnumWrapper<E>(clazz);
  }

  private FieldEnumWrapper(final Class<E> clazz) {
    this.clazz = clazz;
    this.index = Maps.uniqueIndex(
        EnumSet.allOf(clazz), new Function<E, String>() {
          @Override
          public String apply(final E input) {
            return input.searchName();
          }
        });
  }

  public Class<E> clazz() {
    return clazz;
  }

  public Field valueOfSearchName(final String searchName) {
    return index.get(searchName);
  }
}
for (final FieldEnumWrapper<?> fieldEnum : ImmutableList.of(
    FieldEnumWrapper.of(EntityField.class),
    FieldEnumWrapper.of(AddressField.class),
    FieldEnumWrapper.of(PersonFunctionType.class))) {
  valueOfSearchName = fieldEnum.valueOfSearchName("POD_I_OS_PARTNER");
  // ...
FieldEnumWrapper.of(NotEnumAndFieldClass.class)