如何调用泛型的正确工厂方法?
How to call the correct factory method of a generic type?
我正在尝试编写一个泛型 class,它可以通过调用该类型 class:
的静态工厂方法来创建其泛型类型的实例
class Test<T extends Parent> {
public static void main(String[] args) {
new Test<Child>();
}
private Test() {
System.out.println(Child.newInstance());
System.out.println(T.newInstance());
}
}
abstract class Parent {
static <T extends Parent> T newInstance() {
return null;
}
}
class Child extends Parent {
static Child newInstance() {
return new Child();
}
}
我预计 Child.newInstance()
和 T.newInstance()
会调用相同的方法,因为类型 T
被设置为 Child
。但是 T.newInstance()
调用其父类的 class 方法和 returns null
,而直接调用 Child.newInstance()
returns 一个新的 Child
对象.
有人可以解释一下吗,我对 Java 泛型逻辑的误解在哪里,是否有任何其他干净的方法来创建泛型类型的实例?
编辑:我不是要覆盖静态方法,我只是想隐藏它。
感谢类型擦除,我们不知道类型参数是什么。因此,在运行时,我们不知道它是Test<Parent>
、Test<Child>
、Test<Chicken>
等
如果要使用类型参数,则需要传入相关的Class
对象并对其使用反射,如下所示:
public class Test<T extends Parent> {
public static void main(String[] args) {
new Test<Child>(Child.class);
}
private Test(Class<T> clazz) {
System.out.println(Child.newInstance());
try {
System.out.println(clazz.getDeclaredMethod("newInstance").invoke(null));
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}
由于 java 的类型擦除,在 运行 期间每个通用对象都被其上限替换。所以在你的代码中:
class Test<T extends Parent> {
private Test() {
System.out.println(Child.newInstance());
System.out.println(T.newInstance());
}
}
由于 Parent
是上限,因此 test()
最终编译成以下内容,无论您在 class 之外指定什么通用参数:
private Test() {
System.out.println(Child.newInstance());
System.out.println(Parent.newInstance());
}
我正在尝试编写一个泛型 class,它可以通过调用该类型 class:
的静态工厂方法来创建其泛型类型的实例class Test<T extends Parent> {
public static void main(String[] args) {
new Test<Child>();
}
private Test() {
System.out.println(Child.newInstance());
System.out.println(T.newInstance());
}
}
abstract class Parent {
static <T extends Parent> T newInstance() {
return null;
}
}
class Child extends Parent {
static Child newInstance() {
return new Child();
}
}
我预计 Child.newInstance()
和 T.newInstance()
会调用相同的方法,因为类型 T
被设置为 Child
。但是 T.newInstance()
调用其父类的 class 方法和 returns null
,而直接调用 Child.newInstance()
returns 一个新的 Child
对象.
有人可以解释一下吗,我对 Java 泛型逻辑的误解在哪里,是否有任何其他干净的方法来创建泛型类型的实例?
编辑:我不是要覆盖静态方法,我只是想隐藏它。
感谢类型擦除,我们不知道类型参数是什么。因此,在运行时,我们不知道它是Test<Parent>
、Test<Child>
、Test<Chicken>
等
如果要使用类型参数,则需要传入相关的Class
对象并对其使用反射,如下所示:
public class Test<T extends Parent> {
public static void main(String[] args) {
new Test<Child>(Child.class);
}
private Test(Class<T> clazz) {
System.out.println(Child.newInstance());
try {
System.out.println(clazz.getDeclaredMethod("newInstance").invoke(null));
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}
由于 java 的类型擦除,在 运行 期间每个通用对象都被其上限替换。所以在你的代码中:
class Test<T extends Parent> {
private Test() {
System.out.println(Child.newInstance());
System.out.println(T.newInstance());
}
}
由于 Parent
是上限,因此 test()
最终编译成以下内容,无论您在 class 之外指定什么通用参数:
private Test() {
System.out.println(Child.newInstance());
System.out.println(Parent.newInstance());
}