Java 如何仅通过泛型类型T创建实例

Java 如何仅通过泛型类型T创建实例,java,generics,Java,Generics,我只想通过定义泛型类的类型来创建一个实例 public abstract class Base<T> { private final T genericTypeObject; protected Base(){ //Create instance of T here without any argument } } 公共抽象类基类{ 私有final T genericTypeObject; 保护基(){ //在这里不带任何参数创建T的

我只想通过定义泛型类的类型来创建一个实例

public abstract class Base<T> {
    private final T genericTypeObject;

    protected Base(){
          //Create instance of T here without any argument

    }
}
公共抽象类基类{
私有final T genericTypeObject;
保护基(){
//在这里不带任何参数创建T的实例
}
}
这样我就可以调用默认构造函数:

public class Child extends Base<SomeClass>{
    public Child () {
        super();
    }
}
公共类子类扩展基{
公共儿童(){
超级();
}
}

基类实现将为我创建一个GenericType的实例。

您必须有访问该类的权限才能创建实例,因此不可能创建没有参数的实例。您必须通过

更新:


请参阅@JDC的答案。

您必须有访问该类的权限才能创建实例,因此不可能创建没有参数的实例。您必须通过

更新:


请参阅@JDC的答案。

通用信息将在编译时被删除,因此在运行时将不再有
T
)。这就是为什么您需要一个
类来存储信息的原因


在我看来,最干净、最简单的解决方案是将类传递给构造函数。我知道你要求它没有任何构造函数参数,但我认为这是不可能的


代码示例
公共类子类扩展了AbstractBase{
公共儿童(){
super(SomeClass::new);
}
}

通用信息将在编译时被删除,因此在运行时将不再有
T
(您丢失了该信息)。这就是为什么您需要一个
类来存储信息的原因


在我看来,最干净、最简单的解决方案是将类传递给构造函数。我知道你要求它没有任何构造函数参数,但我认为这是不可能的


代码示例
公共类子类扩展了AbstractBase{
公共儿童(){
super(SomeClass::new);
}
}

在运行时,这会返回一个类实例:

public static Class<?> getGenericClassOfType(Object object){
        Class<?> clazz = (Class<?>) ((ParameterizedType) object.getClass() .getGenericSuperclass()).getActualTypeArguments()[0];
        return clazz;
}
公共静态类getGenericClassOfType(对象对象){
Class clazz=(Class)((ParameterizedType)object.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
回击声;
}
之后,我可以通过以下方式开始:

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 static T getDefaultInstance(类clazz)抛出IllegaccessException、InvocationTargetException、InstanceionException{
T实例=null;
构造函数[]构造函数=(构造函数[])clazz.getDeclaredConstructors();
构造函数=null;
对于(建造商cstr:建造商){
//仅当默认构造函数
if(cstr.getParameters().length==0){
构造函数=(构造函数)cstr;
打破
}
}
if(构造函数!=null){
constructor.setAccessible(true);
instance=constructor.newInstance();
}
返回实例;
}
因此,我的基本构造函数中的代码如下所示:

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;
    }
}
公共抽象类BaseScene{
私有最终静态记录器Logger=LogManager.getLogger(BaseScene.class);
私人最终场景控制器;
//公共T getSceneController(){
//返回场景控制器;
//}
受保护的基本场景(){
T newInstance=null;
试一试{
Class clazz=(Class)ReflectionHelper.getGenericClassOfType(this);
newInstance=ReflectionHelper.getDefaultInstance(clazz);
}catch(IllegaAccessException | InvocationTargetException | InstanceionException e){
LOGGER.error(“尝试启动基本场景时出错”,e);
}
sceneController=newInstance;
}
}

在我测试时,它工作得很好

在运行时,这会返回一个类实例:

public static Class<?> getGenericClassOfType(Object object){
        Class<?> clazz = (Class<?>) ((ParameterizedType) object.getClass() .getGenericSuperclass()).getActualTypeArguments()[0];
        return clazz;
}
公共静态类getGenericClassOfType(对象对象){
Class clazz=(Class)((ParameterizedType)object.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
回击声;
}
之后,我可以通过以下方式开始:

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 static T getDefaultInstance(类clazz)抛出IllegaccessException、InvocationTargetException、InstanceionException{
T实例=null;
构造函数[]构造函数=(构造函数[])clazz.getDeclaredConstructors();
构造函数=null;
对于(建造商cstr:建造商){
//仅当默认构造函数
if(cstr.getParameters().length==0){
构造函数=(构造函数)cstr;
打破
}
}
if(构造函数!=null){
constructor.setAccessible(true);
instance=constructor.newInstance();
}
返回实例;
}
因此,我的基本构造函数中的代码如下所示:

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;
    }
}
公共抽象类BaseScene{
私有最终静态记录器Logger=LogManager.getLogger(BaseScene.class);
私人最终场景控制器;
//公共T getSceneController(){
//返回场景控制器;
//}
受保护的基本场景(){
T newInstance=null;
试一试{
Class clazz=(Class)ReflectionHelper.getGenericClassOfType(this);
newInstance=ReflectionHelper.getDefaultInstance(clazz);
}catch(IllegaAccessException | InvocationTargetException | InstanceionException e){
LOGGER.error(“尝试启动基本场景时出错”,e);
}
sceneController=newInstance;
}
}
在我测试时,它工作得很好

你可能会问一个问题,因此你最好解释你的整体问题,而不是你试图(错误地)解决它。你想要一个“干净”的解决方案,还是对一个肮脏的、基于反射的黑客感到满意?我曾经试着做类似的事情,我已经放弃了,但最近我想我已经明白了——尽管如此
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;
    }
}