简体   繁体   English

在Java中使用Enum的泛型

[英]Generics using Enum in Java

I have an enum 我有一个枚举

public enum Days {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY 

} }

I want to make a class which can take values of type days. 我想创建一个可以获取类型为days的值的类。 So i used Java Generics 所以我使用了Java Generics

public class State<T extend Days>

But there is an error 但是有一个错误

The type parameter T should not be bounded by the final type Days. 
Final types cannot be further extended

How can i resolve this? 我该如何解决这个问题?

enums are final types, which means, you can not extend from them 枚举是最终类型,这意味着,您无法从它们扩展

a generic like wants a Class as Parameter which is Days or an extended class, but the extended class is not possible 一般类似想要一个Class作为参数,它是Days或扩展类,但扩展类是不可能的

so the only parameter possible is Days and you don't need a generic, if only one value is possible 因此唯一可能的参数是Days,如果只有一个值,则不需要泛型

Don't use a generics bound. 不要使用泛型绑定。 There's no need. 没有必要。 Just use an unbounded type, like this: 只需使用无界类型,如下所示:

public class State<T> {
    public State(T startState) {
        // whatever
    } 
}

And to use it: 并使用它:

State<Days> dayState = new State<Days>(Days.SUNDAY);

This is a straightforward typed class that doesn't need a bound. 这是一个简单的类型类,不需要绑定。

The only bound that might make sense is a bound to an enum : 可能有意义的唯一界限是enum

public class State<T extends Enum<T>> {
    public State(T startState) {
        // whatever
    } 
} 

This version requires that the generic parameter be an enum . 此版本要求泛型参数为enum With this version the above usage example would still compile, but this would not compile (for example): 使用此版本,上面的用法示例仍然可以编译,但这不会编译(例如):

State<String> dayState = new State<String>("hello");

because String is not an enum . 因为String不是enum

You cannot extend enums in java (http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html towards the end). 你不能在java中扩展枚举(http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html到最后)。 Thus is not possible. 因此是不可能的。

-IF you need your class to work only with your enum you don't need generics -IF你需要你的班级只用你的enum工作,你不需要泛型

-if instead you need it to work with others enum (does it makes sense?) you don't need to specify the extend. - 相反,你需要它与其他枚举(它有意义吗?)你不需要指定扩展。

What does exactly your State class do ? 你的国家班级到底做了什么?

The thing to do here is 这里要做的是

public enum Days{..}

public class State { // no generic argument!
  ...
}

As it stands, you can't have State<T extends Days> because the only way to satisfy T extends Days is to have T be Days . 就目前而言,你不能拥有State<T extends Days>因为满足T extends Days的唯一方法就是让T Days That's what it means for Days to be final . 这就是Days final

So instead, you should make State not generic, and use Days directly everywhere you were trying to use T . 因此,您应该使State 不是通用的,并在您尝试使用T任何地方直接使用Days You can't declare public class State<Days> , because then it'll try to treat Days as a type variable, not as the class Days , and that's not what you want. 你不能声明public class State<Days> ,因为它会尝试将Days视为一个类型变量,而不是类Days ,这不是你想要的。

This compiles fine for me under Java 6: 这在Java 6下编译得很好:

public enum Days {
  SUNDAY, 
  MONDAY, 
  TUESDAY, 
  WEDNESDAY,
  THURSDAY, 
  FRIDAY, 
  SATURDAY
}

public class State<T extends Days> {
  T state;

  public State(T startState) {
    this.state = startState;
  }
}

private void test() {
  State<Days> state = new State<Days> (Days.MONDAY);
}

However, if you want your State object to change from one enum to another you would be better to use something like: 但是,如果您希望State对象从一个enum更改为另一个enum ,那么最好使用以下内容:

public class State<S extends Enum<S>> {
  final ArrayList<S> states = new ArrayList<S>();
  private S state;

  public State(S startState) {
    states.addAll(EnumSet.allOf(startState.getClass()));
    this.state = startState;
  }

  public S next() {
    return state = states.get((state.ordinal() + 1) % states.size());
  }

  public S prev() {
    return state = states.get((state.ordinal() - 1 + states.size()) % states.size());
  }

  public S set(S newState) {
    return state = newState;
  }

  public S get() {
    return state;
  }
}

private void test() {
  State<Days> state = new State<Days> (Days.MONDAY);
  // ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM