java - 当类中没有定义泛型类型变量时处理泛型类成员

标签 java generics

请看下面的代码:

public class MyClass<T extends MyObject> {
    private Class<T> clazz;
    public void setClass1(Class<T> clazz) {
        this.clazz = clazz;
    }
    public Class<T> getClass1() {
        return clazz;
    }
    public T getObject1() {
        T o = null;
        try {
            o = clazz.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return o;
    }
}

上面的效果很好,但需要类类型 T在任何MyClass之前被知道对象被创建。现在,如果我想延迟指定 T直到 setClass1()曾经被调用过,我必须删除 <T extends MyObject>来自 MyClass声明如下:

public class MyClass {
//  private Class<T> clazz; // doesn't work anymore as T is unknown, so do the following instead
    private Class<? extends MyObject> clazz;
    public <T extends MyObject> void setClass1(Class<T> clazz) {
        this.clazz = clazz; // OK
    }
    public void setClass2(Class<? extends MyObject> clazz) {
        this.clazz = clazz; // OK
    }
    public <T extends MyObject> Class<T> getClass1() {
        return clazz; // Error, need casting to Class<T>
    }
    public Class<? extends MyObject> getClass2() {
        return clazz; // OK
    }
    public <T extends MyObject> T getObject1() {
        T o = null;
        try {
            o = clazz.newInstance(); // Error, must cast to T
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return o;
    }
    public MyObject getObject2() {
        MyObject o = null;
        try {
            o = clazz.asSubclass(MyObject.class).newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return o; // OK, but lost the difference between ? extends MyObject and MyObject
    }
}

首先,为什么 getClass1()给出错误,而 setClass1()可以吗?

二、为什么返回getObject1()必须转换为 (T)

三、如何修复getObject1()没有不必要的类型转换,也没有 @SuppressWarnings("unchecked")

第四,在我的例子中会改变使用 setClass1() , getClass1() , getObject1()setClass2() , getClass2() , getObject2()更好?

最佳答案

First, why getClass1() gives error, while setClass1() is OK?

setClass()你分配一个 Class<? extends MyObject>Class<? extends MyObject> 类型的变量.这是允许的。

getClass() ,你想检索一个 Class<T>来自 Class<? extends MyObject> 类型的变量.但是编译器无法知道变量中存储的内容是否真的是 Class<T>。或者可能是 Class<U> .所以这是被禁止的。

Second, why the return in getObject1() must be cast to (T)?

Class<? extends MyObject>.newInstance()返回 ? extends MyObject 类型的对象.这与 T 不同.这就是你必须转换的原因。

Third, how do you fix getObject1() without unnecessary casting nor @SuppressWarnings("unchecked")?

如前所述,上面的版本不包含不必要的转换。你要么必须制作T类本身的通用参数,或者您需要强制转换。

关于java - 当类中没有定义泛型类型变量时处理泛型类成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40124587/

相关文章:

java - 如何在构造函数数组中查找复制构造函数

java - 使用 protected block 同步 Hibernate 插入

java - Guava:是否可以不使用 Multimaps.index() 映射所有条目?

Java游戏。子弹不会直接从 Guzzle 飞出

java - 试图找出为什么我的数学不会相加

c - 是否可以使用泛型而不是仅使用整数在 C 中实现 StackADT?

JavaFX 自定义对话框未居中

c# - Ienumerable 字典数组调用的扩展方法

ios - 快速处理两种不同的值类型

c# - 来自基本接口(interface)的通用类型