没有静态成员可以使用类型参数,但是可以使用泛型类型参数调用静态成员吗?例如:-
abstract class Agent<A>{
void callAgent();
Agent(){
A.add();
}
}
这里add()是一个静态方法。
关于类似主题有一些C#问题和答案,但我不太清楚如何在Java中进行。
如果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支持单个“对象”,它允许参数化功能多态继承。
你不能。编译器不知道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();
}
}
这是不可能的,因为A
类型不一定包含add()
方法。编译器不允许这样做,因为它无法保证它能够正常工作。
实际上,您可以在类型参数上调用静态方法(尽管它不是动态完成的)。
试试这个:
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
。
您可以使用反射来调用类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);
}
}
但我可以得到例外。小心。