是否可以创建通用枚举?

发布于 2024-12-06 18:57:11 字数 373 浏览 0 评论 0原文

我正在尝试定义通用枚举,但遇到了问题:

private enum Stick<T>{
    A, B, C;

    private Stack<T> disks = new Stack();

    public void print(){
        System.out.println(this.name() + ": " + disks);
    }

    public T pop(){
        return disks.pop();
    }

    public void push(T element){
        disks.push(element);
    }

};

这可能吗?

I'm trying to define generic enum, but have problems with it:

private enum Stick<T>{
    A, B, C;

    private Stack<T> disks = new Stack();

    public void print(){
        System.out.println(this.name() + ": " + disks);
    }

    public T pop(){
        return disks.pop();
    }

    public void push(T element){
        disks.push(element);
    }

};

Is it possible at all?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

醉殇 2024-12-13 18:57:11

枚举是常量。因此,堆栈磁盘不能是“枚举客户端想要的任何类型的堆栈”。它必须是固定类型。

枚举中包含字段的目的是能够保存有关每个元素的附加信息。例如,对于堆栈,这可能是 A("a", "b"), B("b", "c", "d") code> - 每个元素指定在其堆栈中加载哪些项目(该示例需要一个 varargs 构造函数)。但它们的类型是严格指定的,不能是

eclipse编译器显示的错误很清楚:

语法错误,枚举声明不能有类型参数

但是,您可以执行类似的操作:

enum Foo {
    A("foo", "bar"),
    B(0, 1, 2);
    private Stack<?> stack;
    private <T> Foo(T... args) {
        stack = new Stack<T>();
        stack.addAll(Arrays.asList(args));
    }
    public <T> Stack<T> getStack() {
        return (Stack<T>) stack;
    }
}

然后:

Stack<String> stack1 = Foo.A.getStack();
Stack<Integer> stack2 = Foo.B.getStack();

System.out.println(stack1);
System.out.println(stack2);

结果:

[foo, bar]
[0, 1, 2]

更新: 由于您对目标的评论 - 河内塔不应该是枚举,因为它们价值观正在改变。相反,您应该使用枚举作为 Map 的键,其中值是堆栈。我承认使用枚举字段来做到这一点看起来很诱人,但这不是一个好的做法。枚举最好保持不变。当然,您可以使用我上面的示例来实现您的初始目标,但我建议您使用Map

Enums are constants. So Stack disks can not be "stack of whatever type the client of the enum wants". It has to be of fixed type.

The point of having fields in an enum is to be able to hold additional information about each element. For example, in the case of a stack, this could be A("a", "b"), B("b", "c", "d") - each element specify what items are loaded in its stack (the example requires a varargs constructor). But their type is strictly specified, it cannot be <T>.

The error that the eclipse compiler shows is clear:

Syntax error, enum declaration cannot have type parameters

However, you can do something like that:

enum Foo {
    A("foo", "bar"),
    B(0, 1, 2);
    private Stack<?> stack;
    private <T> Foo(T... args) {
        stack = new Stack<T>();
        stack.addAll(Arrays.asList(args));
    }
    public <T> Stack<T> getStack() {
        return (Stack<T>) stack;
    }
}

And then:

Stack<String> stack1 = Foo.A.getStack();
Stack<Integer> stack2 = Foo.B.getStack();

System.out.println(stack1);
System.out.println(stack2);

Results in:

[foo, bar]
[0, 1, 2]

Update: Since your comment about your goal - the hanoi towers should not be enums, because their values are changing. Instead, you should use the enums as keys to a Map, where the values are the stacks. I admit that it looks tempting to use a field of the enum to do that, but it is not a good practice. Enums better be constant. Of course, you can use my example above to achieve your initial goal, but I'd recommend a Map.

胡大本事 2024-12-13 18:57:11

不,但枚举可以实现接口。也许这对你有帮助。

No, but Enums can implement interfaces. May be that helps you.

鲸落 2024-12-13 18:57:11

这可能会有所帮助。基本上,你需要这个:

public interface Stick<E extends Enum<E>>

This could help. Basically, you need this:

public interface Stick<E extends Enum<E>>
污味仙女 2024-12-13 18:57:11

这里有一个通用枚举的草案:
http://openjdk.java.net/jeps/301

希望它能进入 Java 10 !

There is a draft for generic enums here:
http://openjdk.java.net/jeps/301

Hope it makes it into Java 10!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文