2012-02-13 72 views
12

使用枚举我有一个枚举泛型在Java中

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

}

我想使一个类可以采取的类型天值。所以我用Java泛型

public class State<T extend Days> 

但有一个错误

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

我该如何解决?

回答

6

不要使用绑定一个仿制药。没有必要。只要使用无界类型,像这样:

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

,并使用它:

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

这是不需要绑定一个简单的类型类。

唯一的约束,且可能是有意义的是绑定到一个enum

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

此版本需要泛型参数是enum。在这个版本上使用示例仍然编译,但这不会(例如)编译:

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

因为String不是enum

+7

这不是OP想要的。 OP只想接受天,而不是任何东西或任何枚举。他不需要泛型就可以做到这一点,他根本不需要使用泛型。 – Malcolm 2012-02-13 12:35:01

+0

@Malcolm嗯,他可以为他的'State'类使用泛型(按照我的代码)。他只是不需要泛型就是有界的。我明白你的意思,但他*可以让他的班级变得通用 - 这似乎是一个方便的班级,可以处理初始/当前状态 – Bohemian 2012-02-13 19:22:59

+1

它不符合OP指定的目的。他需要一个在Days或其子女上工作的课程:“我想创造一个能够接受类型天数值的课程”。由于任何枚举都没有孩子,所以他应该明确写出Days。您的代码不会将这些值限制为Days。 – Malcolm 2012-02-13 19:28:36

5

您不能在java中扩展枚举(http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html到最后)。因此是不可能的。

- 如果您需要您的类只与你的枚举工作,你并不需要仿制药

- 如果不是你需要它与其他枚举工作(它是有道理的?)你不需要指定扩展。

你的州立班究竟做了什么?

9

枚举是最后的类型,这意味着,你不能从他们

通用延长像想一类作为参数,它是天或扩展类,而是扩展的类是不可能

所以唯一可能的参数是天,你并不需要一个通用的,如果只有一个值可能

+1

-1您在这里错过了重点。任何类型都是可能的 - 这是一个通用的州级课程。 – Bohemian 2012-02-13 12:13:28

+0

@Bohemian不,我认为你是错过了这一点。看到你的答案评论。 – Malcolm 2012-02-13 12:35:37

2

这对我来说编译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); 
} 

但是,如果你希望你的State对象从一个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); 
    // ... 
} 
+0

'this.states =(S [])states.toArray();'抛出'ClassCastException'!我正在研究解决方案。 – OldCurmudgeon 2012-02-13 13:14:37

+0

修复了'ClassCastException'问题! – OldCurmudgeon 2012-02-13 13:28:16

+0

但S仍然可以是任何枚举,它不一定是'Days'枚举... – FBB 2015-09-03 08:52:45

5

在这里做的事情是

public enum Days{..} 

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

既然这样,你不能有State<T extends Days>因为满足T extends Days的唯一途径是让TDays。这就是Daysfinal

因此,相反,你应该让State通用,并且使用Days直接无处不在,你试图使用T。你不能声明public class State<Days>,因为它会尝试将Days作为变量类型,不作为Days类别,那就是而不是你想要什么。