2

I have a set of basic classes, ei:

public class Item{ }

I want to add feature to extend basic class with Storable ability:

  1. new parameter to keep data from storage in an object
  2. new static method to load objects from storage

I created an abstract class Storable:

public abstract class Storable{
    private StorageRow str;

    public void setStorageRow(StorageRow row){
        str = row;
    }

    public static ArrayList<? extends Storable> getAll(){
        ArrayList<Storable> ans = new ArrayList<Storable>();
        Class<Storable> extenderClass = ??????


        ArrayList<StorageRow> rows = Storage.get(llallala);
        for(StorageRow row : rows){
            Object extender = extenderClass.newInstance();
            // Now with reflection call to setStorageRow(row);
        }
        return ans;
    }
}

Now I extend my basic class with Storable:

public class Item extends Storable{}

The call is:

ArrayList<Item> items = (ArrayList<Item>) Item.getAll();

The main question is: Now I'm inside static method getAll of superclass. How to get a subclass?

Andrey
  • 853
  • 9
  • 27
  • 1
    Not quite sure what you're trying to do, but the short answer is you probably can't. But you could probably add an `Item.getAll()` method which used `Storable.getItem()`. – Rob I Apr 12 '13 at 18:10
  • 2
    if you want your load method to behave polymorphically you can't make it static. – Nathan Hughes Apr 12 '13 at 18:14

1 Answers1

2

You can't. Static methods belong to the class where you declared it, not to its children (they're not inherited). So if you want to know from where it was called, you need to pass the class as argument to it.

public static ArrayList<? extends Storable> getAll(Class<? extends Storable>)

Another more cumbersome way to do it is to get the stack trace and check which class did the call, but I don't think this kind of hack is worth it when an argument suffices.

EDIT: example using the stacktrace:

class AnotherClass {

    public AnotherClass() {
        Main.oneStaticMethod();
    }
}

public class Main {

    /**
     * @param args
     * @throws OperationNotSupportedException
     */
    public static void main(final String[] args) {
        new AnotherClass();
    }

    public static void oneStaticMethod() {
        final StackTraceElement[] trace = Thread.currentThread()
                .getStackTrace();
        final String callingClassName = trace[2].getClassName();
        try {
            final Class<?> callingClass = Class.forName(callingClassName);
            System.out.println(callingClass.getCanonicalName());
        } catch (final ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
Community
  • 1
  • 1
m0skit0
  • 25,268
  • 11
  • 79
  • 127
  • In my opinion, this is the easy way and it will sure work. The disadvantage is that the code looks ugly: Item.getAll(Item.class) The trick with stack didn't work to me, 'cause I see superclass in stack, not subclass – Andrey Apr 12 '13 at 18:21
  • I've added an example on how to get the class calling a static method using the stacktrace. Best idea for this would be to create a static `Class> getCallingClass()` method and use it whenever necessary. I still think first way is better because it's simpler, more maintainable, more readable... – m0skit0 Apr 12 '13 at 18:40