怎样理解java泛型中的擦除

class GenericBase {
private T element;
public void set(T arg) { arg = element; }
public T get() { return element; }
}

class Derived1 extends GenericBase {}

class Derived2 extends GenericBase {} //这里去除了T,为什么编译时没有问题?

// class Derived3 extends GenericBase<?> {}
// 上面的GenericBase<?>会出现编译错误,这又是为什么?

public class ErasureAndInheritance {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
Derived2 d2 = new Derived2();
Object obj = d2.get();
d2.set(obj); // 如果上面没有@SuppressWarnings修饰的话,这里会出现一个编 译警告,为什么偏偏在set()方法这里出现一个编译警告?
}
}

6个回答

【1】class Derived2 extends GenericBase {} //这里去除了T,为什么编译时没有问题?
经过测试这种继承方法,是不继承父类泛型效果的,,可能就是题主所说的对父类的泛型擦除

还可以这样继承,给子类设置泛型,class Derived2 extends GenericBase {},,,和上面一样,父类的泛型效果未被继承

【2】 class Derived3 extends GenericBase<?> {} 上面的GenericBase<?>会出现编译错误,这又是为什么?
父类设置了泛型,子类没有泛型,,创建自类时如何给父类设置泛型??所以系统报错“找不到泛型”
必须给子类和父类设置泛型(且名字相同,测试了一下同时设置 ? 是不行的),
class Derived2 extends GenericBase(名字随意,但要一样)

【3】d2.set(obj); // 如果上面没有@SuppressWarnings修饰的话,这里会出现一个编 译警告,为什么偏偏在set()方法这里出现一个编译警告?
泛型默认是 Object 类型的,,get到一个object不会有问题吧,,,
set不同,,set需要把你的对象赋值给泛型的对象,,这是有危险的,需要设置泛型才可以取出警告。
编译器报错,给了个map的例子,大概意思是说“没有指定泛型的地方,赋值都会出现警告。”,,下面有个List的例子:

        List list = new ArrayList();
        list.add("sss");//有警告

我也是根据测试结果总结的,欢迎交流,,,,有问题还可以追问
我的测试代码如下:

 public class TestT {
    //    @SuppressWarnings("unchecked")
    public static void main(String[] args) {
        Derived2<String> d2 = new Derived2<String>();
        Object obj = "aaa";
        d2.set((String) obj);
        System.out.println(d2.get());

        List list = new ArrayList();
        list.add("sss");//有警告

        GenericBase<String> genericBase = new GenericBase<>();
        genericBase.set("sss");//没警告
    }
}

class GenericBase<T> {
    private T element;

    public void set(T arg) {
        element = arg;
    }

    public T get() {
        return element;
    }
}

class Derived1 extends GenericBase {
}

class Derived2<S> extends GenericBase<S> {
}
Small_Mouse0
鼠小 纯手敲,,对你有帮助,,别忘了给个采纳,谢谢
大约 3 年之前 回复

通配符 并不适用于函数声明

class GenericBase {
private T element;
public void set(T arg) { arg = element; }
public T get() { return element; }
}
class Derived1 extends GenericBase {}
前面一部分是这样的

class GenericBase《T》 {
private T element;
public void set(T arg) { arg = element; }
public T get() { return element; }
}
class Derived1《T》 extends GenericBase《T》 {}
前面一部分是这样的

public void set(T arg) { arg = element; }这句写错了--不能把一个未初始化的值传给参数,应该是public void set(T arg) { this.element = arg; }

泛型只是一种自检手段,以便在编译前纠错,编译的时候会补偿去掉

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐