Declaring static generic variables in a generic class

前端 未结 4 622
难免孤独
难免孤独 2021-02-13 13:43

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

相关标签:
4条回答
  • 2021-02-13 14:07

    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.

    0 讨论(0)
  • 2021-02-13 14:09

    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
        }
    }
    
    0 讨论(0)
  • 2021-02-13 14:09

    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.

    0 讨论(0)
  • 2021-02-13 14:14

    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

    0 讨论(0)
提交回复
热议问题