Java 使用泛型类型调用静态方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6512179/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Calling a static method using generic type
提问by aps
No static member can use a type parameter, but is it possible to call a static member using the generic type parameter? For example:-
静态成员不能使用类型参数,但是否可以使用泛型类型参数调用静态成员?例如:-
abstract class Agent<A>{
void callAgent();
Agent(){
A.add();
}
}
Here add() is a static method.
这里 add() 是一个静态方法。
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 中进行。
采纳答案by Adam Gent
No you cannot do it if A is a generic type. (Bozho answered to fast :) and probably thought A was concrete type.
不,如果 A 是泛型类型,则不能这样做。(Bozho 回答很快:)并且可能认为 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. 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.
另一种选择是 Scala。Java 不对静态方法进行继承,因此您无法获得参数化模块(某些语言中的函数组,这称为函子 ... ocaml)。然而,Scala 支持一个允许参数函数多态继承的单例“对象”。
回答by Bozho
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. If you want specific behaviour for each type, define it as non-static, use extends BaseClass
in the generics declaration, and invoke it.
并且您首先不需要对泛型类型调用静态方法。如果您想要每种类型的特定行为,请将其定义为非静态,extends BaseClass
在泛型声明中使用并调用它。
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();
}
}
回答by Marcelo
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.
这是不可能的,因为A
类型不一定包含add()
方法。编译器不会允许这样做,因为它不能保证它会工作。
回答by Paul Boddington
In fact, you caninvoke 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.
我不知道为什么语言设计者认为允许这样做是个好主意。
回答by Ferran Maylinch
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
太多。
回答by Alex
You can use reflection for calling static method of class T. For example:
您可以使用反射来调用类 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);
}
}
But i can get exception. Be careful.
但我可以得到例外。当心。