Java 在泛型类中声明静态泛型变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6577089/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Declaring static generic variables in a generic class
提问by Tanax
I've read that you cannot declare static variables/methods inside a generic class and I really have no idea how to solve my problem or work around it so I ask for your guidance.
我读过你不能在泛型类中声明静态变量/方法,我真的不知道如何解决我的问题或解决它,所以我请求你的指导。
What I want is a generic "index" that all of my core classes will extend.
I'm creating a game-engine and an example is that I will have different gamestates who all extends State
who in turn extends Nexus<State>
. The reason I want the static head and tail is so that I can keep a linked list of all gamestates since they're all added to that list upon creation.
我想要的是一个通用的“索引”,我的所有核心类都将扩展它。我正在创建一个游戏引擎,一个例子是我将有不同的游戏状态,它们都扩展了State
who 依次扩展Nexus<State>
. 我想要静态头部和尾部的原因是我可以保留所有游戏状态的链接列表,因为它们都在创建时添加到该列表中。
Another example is that I will have different gameobjects who all extends GameObject
who in turn extends Nexus<GameObject>
.
另一个例子是,我将有不同的游戏对象,它们都扩展了GameObject
who 依次扩展Nexus<GameObject>
。
This is the index called Nexus
:
这是名为 的索引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;
}
}
If anyone got another solution or a workaround I'm all ears!
如果有人有其他解决方案或解决方法,我会全力以赴!
采纳答案by Bohemian
Try this approach: Define a protected abstract
method that subclasses implement to return a static
object for theirclass.
试试这个方法:定义一个protected abstract
子类实现的方法,static
为它们的类返回一个对象。
There may be some logic issues etc, but the basics of the answer are here (ie this compiles):
可能存在一些逻辑问题等,但答案的基础在这里(即编译):
EDITED: Now delegatingto HeadAndTail
编辑:现在委托给 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
}
}
回答by Tom Busby
according to http://download.oracle.com/javase/tutorial/java/IandI/abstract.html
根据http://download.oracle.com/javase/tutorial/java/IandI/abstract.html
Class Members- An abstract class may have static fields and static methods. You can use these static members with a class reference—for example, AbstractClass.staticMethod()—as you would with any other class.
类成员- 抽象类可能具有静态字段和静态方法。您可以像使用任何其他类一样将这些静态成员与类引用一起使用,例如 AbstractClass.staticMethod()。
But I haven't yet tested this myself
但我还没有亲自测试过
回答by Petar Ivanov
Java generics are quite different than C# generics.
There is type erasure, so you can't say something like Nexus<T>.aStaticPublicField
(as in C#).
You can only say Nexus.aStaticPublicField
.
There is no way to know what the generic type is (as you don't have an instance), so therefore you can't have a static field of type T.
Java 泛型与 C# 泛型完全不同。有类型擦除,所以你不能说Nexus<T>.aStaticPublicField
(如在 C# 中)。你只能说Nexus.aStaticPublicField
。无法知道泛型类型是什么(因为您没有实例),因此您不能拥有 T 类型的静态字段。
回答by bobbymcr
A set of static fields is not a very good way to achieve this. I don't quite understand your requirements but it seems like a better way would be to change the signature of the constructor for this class to pass in the global index object.
一组静态字段不是实现这一点的好方法。我不太明白您的要求,但似乎更好的方法是更改此类的构造函数的签名以传入全局索引对象。
That is, instead of this:
也就是说,而不是这样:
protected Nexus() { this.Add( (T)this ); }
... you could do this instead:
...你可以这样做:
protected Nexus(GameStateIndex<T> index) { index.Add(this); }
This properly separates the responsibilities of tracking the game state and keeping track of the index of all game states. (See the "Single responsibility principle".) It also makes it explicitly clear that creation of a state object comes with a dependency on indexing that state properly.
这适当地分离了跟踪游戏状态和跟踪所有游戏状态索引的职责。(请参阅“单一职责原则”。)它还明确说明了状态对象的创建依赖于正确索引该状态。