Java 泛型笔试问题?

代码:

public class Pair<T> {

    private T t1;
    private T t2;
    
    public T getT1() {
        return t1;
    }
    public void setT1(T t1) {
        this.t1 = t1;
    }
    public T getT2() {
        return t2;
    }
    public void setT2(T t2) {
        this.t2 = t2;
    }
}

public class User {

    private String name;
    private String sex;
    private Integer age;
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
}

public class  Twins extends Pair<User> {

    @Override
    public void setT1(User t1) {
        if (t1 != null) {
            super.setT1(t1);
        }
    }

    @Override
    public void setT2(User t2) {
        if (t2 != null) {
            super.setT2(t2);
        }
    }
}

问题描述:虚拟机会将 Pair进行类型擦除,擦出后类型变量将替换为 Object,那么 Twins 类重写的方法 void setT1(User t1)void setT2(User t2)中参数会擦出为 Object吗?为什么?

阅读 2.5k
3 个回答

Twins的方法参数User类型不会被擦除, 因为已经做了类型绑定.

如果执行new Twins().setT1(new Object())
会报如下错:

Twins Caught: java.lang.ClassCastException: java.lang.Object cannot be
cast to User java.lang.ClassCastException: java.lang.Object cannot be
cast to User at Twins.setT1(temp.groovy) at Pair$setT1.call(Unknown
Source)

官方文档原文是这么写的:

Type Erasure Generics were introduced to the Java language to provide
tighter type checks at compile time and to support generic
programming. To implement generics, the Java compiler applies type
erasure to:

Replace all type parameters in generic types with their bounds or
Object if the type parameters are unbounded. The produced bytecode,
therefore, contains only ordinary classes, interfaces, and methods.
Insert type casts if necessary to preserve type safety. Generate
bridge methods to preserve polymorphism in extended generic types.
Type erasure ensures that no new classes are created for parameterized
types; consequently, generics incur no runtime overhead.

参考:
https://docs.oracle.com/javas...

@潘金莲的答案更确切些

父类Pair进行类型擦除,擦出后类型变量将替换为Object,子类 Twins 类重写的方法 void setT1(User t2)及 void setT2(User t2)不会被擦出为Object,但这样参数列表变了,不是重写了,所以子类Twins自动生成了两个方法setT1(java.lang.Object)和setT2(java.lang.Object)方法重写父类两个方法,在里面调用void setT1(User t2)及 void setT2(User t2)这两个方法,所以子类Twins是有四个方法.

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题