在泛型类中声明静态泛型变量

时间:2011-07-05 00:35:37

标签: java list generics static linked-list

我读过你不能在泛型类中声明静态变量/方法,我真的不知道如何解决我的问题或解决它,所以我请求你的指导。

我想要的是一个通用的“索引”,我的所有核心类都将扩展。 我正在创建一个游戏引擎,一个例子是我将拥有不同的游戏状态,所有游戏状态都延伸State,而Nexus<State>又延伸GameObject。我想要静态头部和尾部的原因是我可以保留所有游戏状态的链接列表,因为它们在创建时都被添加到该列表中。

另一个例子是我会有不同的游戏对象,他们都延伸Nexus<GameObject>,而Nexus又延伸public abstract class Nexus<T> { private static T head = null; private static T tail = null; private T next = null; private static int num = 0; protected Nexus() { this.Add( (T)this ); } public T Add( T obj ) { ((Nexus)obj).next = null; if( num++ == 0 ) head = tail = obj; else tail = ( tail.next = obj ); return obj; } }

这是名为{{1}}的索引:

{{1}}

如果有人得到另一种解决方案或解决方法,我会全力以赴!

4 个答案:

答案 0 :(得分:10)

Java泛型与C#泛型完全不同。 有类型擦除,所以你不能说像Nexus<T>.aStaticPublicField(如在C#中)。 你只能说Nexus.aStaticPublicField。 无法知道泛型类型是什么(因为您没有实例),因此您不能拥有T类型的静态字段。

答案 1 :(得分:9)

尝试此方法:定义子类实现的protected abstract方法,以返回类的static对象。

可能存在一些逻辑问题等,但答案的基础在这里(即编译):

已编辑:现在delegating到HeadAndTail

/** <T> A subclass of Nexus */
abstract class Nexus<T extends Nexus<T>> { // This syntax lets you confine T to a subclass of Nexus
    private T next;

    protected Nexus() {
        this.add((T) this);
    }

    public T add(T obj) {
        // Delegate to HeadAndTail
        return getHeadAndTail().add(obj);
    }

    /** @return a static for the class */
    protected abstract HeadAndTail<T> getHeadAndTail();
}

/** Bundled into one Object for simplicity of API */
class HeadAndTail<T extends Nexus<T>> {
    T head = null;
    T tail = null;
    int num = 0;

    public T add(T obj) {
        obj.next = null;
        if (num++ == 0)
            head = tail = obj;
        else
            tail = tail.next = obj;

        return obj;
    }
}

class ConcreteNexus extends Nexus<ConcreteNexus> {
    // This is the static object all instances will return from the method
    private static HeadAndTail<ConcreteNexus> headAndTail = new HeadAndTail<ConcreteNexus>();

    protected HeadAndTail<ConcreteNexus> getHeadAndTail() {
        return headAndTail; // return the static
    }
}

答案 2 :(得分:1)

根据http://download.oracle.com/javase/tutorial/java/IandI/abstract.html

  

班级成员 -   抽象类可以具有静态字段和静态方法。您可以将这些静态成员与类引用一起使用 - 例如,AbstractClass.staticMethod() - 就像使用任何其他类一样。

但我自己还没有测试过这个

答案 3 :(得分:0)

一组静态字段不是实现此目的的好方法。我不太了解您的要求,但似乎更好的方法是更改​​此类的构造函数的签名以传入全局索引对象。

即代替:

protected Nexus() { this.Add( (T)this ); }

......你可以这样做:

protected Nexus(GameStateIndex<T> index) { index.Add(this); }

这恰当地分离了跟踪游戏状态和跟踪所有游戏状态的索引的责任。 (参见“Single responsibility principle”。)它还明确表明,状态对象的创建伴随着对索引状态的依赖。