简体   繁体   English

使用泛型类型调用 static 方法

[英]Calling a static method using generic type

No static member can use a type parameter, but is it possible to call a static member using the generic type parameter?没有 static 成员可以使用类型参数,但是否可以使用泛型类型参数调用 static 成员? For example:-例如:-

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

Here add() is a static method.这里 add() 是一个 static 方法。

There are some C# questions and answers on a similar topic but I'm not too sure how to go about it in Java.有一些关于类似主题的 C# 问题和答案,但我不太确定如何在 Java 中讨论它。

No you cannot do it if A is a generic type.不,如果 A 是泛型类型,则不能这样做。 (Bozho answered to fast:) and probably thought A was concrete type. (博卓回答得很快:)可能还以为A是具体的类型。

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() .您的子类必须覆盖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.如果你仍然不喜欢,你可以看看 AspectJ,它可以让你做一些构造函数(看看 spring 如何做@Configurable),但这变得更加棘手和复杂。

Another option is Scala.另一种选择是 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). Java 在 static 方法上不执行 inheritance,因此您无法获得参数化模块(某些语言中的函数组,这称为函子。) However Scala supports a singleton "object" that does allow for parametric functional polymorphic inheritance.然而,Scala 支持 singleton“对象”,它允许参数功能多态 inheritance。

No, you cannot.你不能。 The compiler does not know A (which resolves to Object ) has the add method.编译器不知道A (解析为Object )具有 add 方法。

And you shouldn't need to invoke static methods on generic types in the first place.而且您首先不需要在泛型类型上调用 static 方法。 If you want specific behaviour for each type, define it as non-static, use extends BaseClass in the generics declaration, and invoke it.如果您想要每种类型的特定行为,请将其定义为非静态,在 generics 声明中使用extends BaseClass并调用它。

Technically, you can also invoke a static method that way, but it's ugly:从技术上讲,您也可以这样调用 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();
    }
}

This is not possible because the A type will not necessarily contain an add() method.这是不可能的,因为A类型不一定包含add()方法。 The compiler will not permit this, because it can't guarantee that it will work.编译器不允许这样做,因为它不能保证它会工作。

In fact, you can invoke a static method on a type parameter (although it isn't done dynamically).实际上,您可以在类型参数上调用 static 方法(尽管它不是动态完成的)。

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.我不知道为什么语言设计者认为允许这样做是个好主意。

It is handy to get a value from an enum you don't know beforehand.从事先不知道的枚举中获取值很方便。

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

Having:有:

enum ProductType { FOOD, ELECTRONICS, ... }

You can do:你可以做:

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

I guess you can also take advantage of this in your own classes, although I would not recommend using static too much.我想您也可以在自己的课程中利用这一点,尽管我不建议过多地使用static

You can use reflection for calling static method of class T. For example:您可以使用反射来调用 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);
    }
}

But i can get exception.但我可以得到例外。 Be careful.当心。

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

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