我想通过定义泛型类
的类型来创建实例public abstract class Base<T> {
private final T genericTypeObject;
protected Base(){
//Create instance of T here without any argument
}
}
这样我就可以调用默认构造函数:
public class Child extends Base<SomeClass>{
public Child () {
super();
}
}
并且Base-class实现将创建GenericType的实例。
答案 0 :(得分:4)
通用信息将在编译时删除,因此在运行期间将不再有T
(您放弃了信息)。这就是为什么你在某个地方需要Class<>
来存储信息。
最干净的&amp;我的观点是简单的解决方案是将类传递给构造函数。我知道你要求它没有任何构造函数参数,但我不认为这是可能的。
public abstract class AbstractBase<T> {
private final T genericTypeObject;
protected Base(Class<T> type){
try {
genericTypeObject = type.newInstance();
} catch (InstantiationException e) {
// Handle
} catch (IllegalAccessException e) {
// Handle
}
}
}
public class Child extends Base<SomeClass> {
public Child () {
super(SomeClass.class);
}
}
使用Supplier
(感谢评论@Jorn Vernee):
public abstract class AbstractBase<T> {
private final T genericTypeObject;
public AbstractBase(Supplier<T> supplier) {
genericTypeObject = supplier.get();
}
}
public class Child extends AbstractBase<SomeClass> {
public Child() {
super(SomeClass::new);
}
}
答案 1 :(得分:1)
在运行时,这会返回一个Class实例:
public static Class<?> getGenericClassOfType(Object object){
Class<?> clazz = (Class<?>) ((ParameterizedType) object.getClass() .getGenericSuperclass()).getActualTypeArguments()[0];
return clazz;
}
然后我可以用以下方式启动它:
public static <T> T getDefaultInstance(Class<T> clazz) throws IllegalAccessException, InvocationTargetException, InstantiationException {
T instance = null;
Constructor<T>[] constructors = (Constructor<T>[]) clazz.getDeclaredConstructors();
Constructor<T> constructor = null;
for (Constructor cstr : constructors) {
//Only if default constructor
if (cstr.getParameters().length == 0) {
constructor = (Constructor<T>) cstr;
break;
}
}
if (constructor != null) {
constructor.setAccessible(true);
instance = constructor.newInstance();
}
return instance;
}
所以我的基础构造函数中的代码如下所示:
public abstract class BaseScene<T extends SceneController> {
private final static Logger LOGGER = LogManager.getLogger(BaseScene.class);
private final T sceneController;
//public T getSceneController() {
// return sceneController;
//}
protected BaseScene(){
T newInstance = null;
try {
Class<T> clazz = (Class<T>)ReflectionHelper.getGenericClassOfType(this);
newInstance = ReflectionHelper.getDefaultInstance(clazz);
} catch (IllegalAccessException | InvocationTargetException | InstantiationException e) {
LOGGER.error("Error while trying to initiate BaseScene",e);
}
sceneController = newInstance;
}
}
在我测试时效果很好。
答案 2 :(得分:0)
您必须有权访问该类才能创建实例,因此无法创建不带参数的实例。您必须传递Class<T>
。
更新:
请参阅@JDC的答案。