这里已有太多帖子暗示:
class Foo<T>{
Class<T> type;
public Foo(Class<T> type){
this.type = type;
}
// then using newInstance method creating the instance
}
这种方法的问题在于,这不是创建实例的java,这是开发人员被迫将类型传递给Foo
类的构造函数。所以,让我们说我需要一个无参数构造函数,Java仍然能够创建实例吗?
例如在C#中我们得到了Activator类型,我们可以这样使用:
Object obj = Activator.CreateInstance<T>();
所以,如果我在Java中使用以下类,并且我无法遵循第一个解决方案,那么什么是类似于C#解决方案的替代方法:
class Foo<T>(){
public Foo(){
if T is of Type X Then Do Y
}
}
答案 0 :(得分:1)
不,你不能这样做。通用参数只是编译时,它们被完全擦除并在运行时变得不可用。
另请注意,无论您是Activator.CreateInstance<Foo>()
(如果可能)还是Activator.CreateInstance(Foo.class)
,您实际上都将相同的确切信息传递给CreateInstance
方法,区别在于纯语法。
答案 1 :(得分:0)
如果真的需要这样做,那么这是可能的。
例如,一些依赖注入框架使用Instance<T>
字段来解析和/或在运行时创建依赖项。
您可以通过经典反射调用获取Class<T>
个对象:
Class<T> cls = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
检查此答案,了解代码段https://stackoverflow.com/a/3942033/2892277
但是(正如那个答案所提到的),这不是一个好习惯。
答案 2 :(得分:0)
如果开发人员创建了Foo
的子类,那么您可以使用TypeTools等内容恢复T
。例如:
public class StringFoo extends Foo<String>{}
Class<?> t = TypeResolver.resolveRawArgument(Foo.class, StringFoo.class);
assert t == String.class;
如果用户没有将Foo子类化并仅仅实例化它,则T
的值无法在运行时恢复。