Calling a static method using generic type

This is not possible because the A type will not necessarily contain an add() method. The compiler will not permit this, because it can't guarantee that it will work.


No you cannot do it if A is a generic type. (Bozho answered to fast :) and probably thought A was concrete type.

What will work is the following.

abstract class Agent extends Blah<ConcreteA>{
    void callAgent();
    Agent() {
        ConcreteA.add();
    }
}

but it's probably not what you want to do.

After reading your comments it sounds like what you really want to do is:

abstract class Agent<A extends SomeClassThatSupportsAdd> {

    void callAgent();
    protected abstract A createNew();

    Agent() {
        A a = createNew();
        A.add();
    }
}

Your subclasses will have to override createNew().

If you still do not like that you can take a look at AspectJ which will allow you to do some constructor magic (see how spring does @Configurable) but that gets far trickier and complicates things.

Another option is Scala. Java does not do inheritance on static methods so you can't get parameterized modules (groups of functions in some languages this is called a functor ... ocaml). However Scala supports a singleton "object" that does allow for parametric functional polymorphic inheritance.


In fact, you can invoke a static method on a type parameter (although it isn't done dynamically).

Try this:

public class Main<T extends Collections> {

    public static void main(String[] args) {
        new Main<>().foo();
    }

    void foo() {
        List<Integer> list = Arrays.asList(2, 3, 1);
        T.sort(list);
        System.out.println(list);
    }
}

I have no idea why the language designers decided it was a good idea to allow this.


No, you cannot. The compiler does not know A (which resolves to Object) has the add method.

And you shouldn't need to invoke static methods on generic types in the first place. If you want specific behaviour for each type, define it as non-static, use extends BaseClass in the generics declaration, and invoke it.

Technically, you can also invoke a static method that way, but it's ugly:

class Base {
    public static void add() { }
}

class Foo<A extends Base> {
    void bar() {
        A a = null; // you can't use new A()!
        a.add();
    }
}