繁体   English   中英

使用泛型类型调用 static 方法

[英]Calling a static method using generic type

没有 static 成员可以使用类型参数,但是否可以使用泛型类型参数调用 static 成员? 例如:-

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

这里 add() 是一个 static 方法。

有一些关于类似主题的 C# 问题和答案,但我不太确定如何在 Java 中讨论它。

不,如果 A 是泛型类型,则不能这样做。 (博卓回答得很快:)可能还以为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 在 static 方法上不执行 inheritance,因此您无法获得参数化模块(某些语言中的函数组,这称为函子。) 然而,Scala 支持 singleton“对象”,它允许参数功能多态 inheritance。

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

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

从技术上讲,您也可以这样调用 static 方法,但这很丑:

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

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

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

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

尝试这个:

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

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

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

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

您可以使用反射来调用 class T 的 static 方法。例如:

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

但我可以得到例外。 当心。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM