使用泛型类型调用静态方法

时间:2011-06-28 19:40:17

标签: java generics static

没有静态成员可以使用类型参数,但是可以使用泛型类型参数调用静态成员吗​​?例如: -

abstract class Agent<A>{
    void callAgent();
    Agent(){
        A.add();                    
    }
}

这里add()是一个静态方法。

在类似主题上有一些C#问题和答案,但我不太清楚如何用Java来解决它。

6 个答案:

答案 0 :(得分:7)

如果A是泛型类型,请不要这样做。 (Bozho快速回答:)并且可能认为A是具体类型。

以下内容将起作用。

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

但这可能不是你想要做的。

阅读完评论之后,您真正想要做的就是:

abstract class Agent<A extends SomeClassThatSupportsAdd> {

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

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

您的子类必须覆盖createNew()

如果你仍然不喜欢它,你可以看一下AspectJ,它可以让你做一些构造函数魔法(看看spring如何做@Configurable)但是这会变得更加棘手并使事情变得复杂。

另一种选择是Scala。 Java不会对静态方法进行继承,因此您无法获取参数化模块(某些语言中的函数组称为函数... ocaml)。但是,Scala支持单个“对象”,它允许参数化功能多态继承。

答案 1 :(得分:6)

不,你不能。编译器不知道A(解析为Object)具有add方法。

首先,您不需要在泛型类型上调用静态方法。如果您想要为每种类型定义特定行为,请将其定义为非静态,在泛型声明中使用extends BaseClass,然后调用它。

从技术上讲,你也可以通过这种方式调用静态方法,但这很难看:

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

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

答案 2 :(得分:2)

这是不可能的,因为A类型不一定包含add()方法。编译器不允许这样做,因为它无法保证它能够正常工作。

答案 3 :(得分:1)

实际上,可以在类型参数上调用静态方法(尽管它不是动态完成的)。

试试这个:

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);
    }
}

我不知道为什么语言设计师认为允许这样做是个好主意。

答案 4 :(得分:0)

从你事先不知道的枚举中获取价值是很方便的。

public static <T extends Enum<T>> T enumFromName(String name, Class<T> clazz) {
    return StringUtils.isEmpty(value) ? null : T.valueOf(clazz, name);
}

有:

enum ProductType { FOOD, ELECTRONICS, ... }

你可以这样做:

ProductType p = enumFromName("FOOD", ProductType.class);

我想您也可以在自己的课程中利用这一点,但我不建议过多地使用static

答案 5 :(得分:0)

您可以使用反射来调用T类的静态方法。例如:

public Agent<T>{

    private final Class<T> clazz;

    public Agent(Class<T> clazz){
        this.clazz = clazz;
        executeAddMethodOfGenericClass();
    }

    public void executeAddMethodOfGenericClass() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Method method = clazz.getMethod("add");
        method.invoke(null);
    }
}

但是我可以得到例外。小心点。