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
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.
Try this approach: Define a protected abstract
method that subclasses implement to return a static
object for their class.
There may be some logic issues etc, but the basics of the answer are here (ie this compiles):
EDITED: Now delegating to 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
}
}
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.
according to 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.
But I haven't yet tested this myself