方法在java中过度加载,导致编译时错误

方法在java中过度加载,导致编译时错误,java,generics,Java,Generics,下面的代码给出了编译时错误,如 '方法打印(列表)与类型MethodOverloadingGenericeExample中的另一个方法具有相同的擦除打印(列表)' public static void main(String[] args) { } public void print(List<Employee> empList){ System.out.println(empList); } public void print(List<Address>

下面的代码给出了编译时错误,如

'方法打印(列表)与类型MethodOverloadingGenericeExample中的另一个方法具有相同的擦除打印(列表)'

public static void main(String[] args) {

}

public void print(List<Employee> empList){
    System.out.println(empList);
}

public void print(List<Address> empList){
    System.out.println(empList);
}

class Employee {
    private String name;

    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}

class Address {
    public int pincode;

    public void setPincode(int pincode) {
        this.pincode = pincode;
    }
    public int getPincode(){
        return pincode;
    }
}
publicstaticvoidmain(字符串[]args){
}
公共作废打印(员工列表){
System.out.println(雇主);
}
公共作废打印(员工列表){
System.out.println(雇主);
}
班级员工{
私有字符串名称;
公共void集合名(字符串名){
this.name=名称;
}
公共字符串getName(){
返回名称;
}
}
班级地址{
公共int pincode;
公共无效setPincode(int pincode){
this.pincode=pincode;
}
公共int getPincode(){
返回pincode;
}
}

泛型类型参数在编译时,因此这两种方法无法区分,这就是为什么它是错误的原因。

泛型在编译时检查类型正确性。然后在一个称为类型擦除的过程中删除泛型类型信息。例如,列表将转换为非泛型类型列表,该列表通常包含任意对象。编译时检查确保生成的代码类型正确

由于类型擦除,无法在运行时确定类型参数。例如,在运行时检查ArrayList时,没有通用的方法来确定在类型擦除之前它是ArrayList还是ArrayList。许多人对这一限制感到不满。[6]有一些片面的做法。例如,可以检查单个元素以确定它们所属的类型;例如,如果ArrayList包含整数,则该ArrayList可能已使用Integer参数化(但是,它可能已使用Integer的任何父级参数化,例如Number或Object)


有关详细信息,请参阅编译时错误处的类型擦除问题部分,如….方法打印(列表)与类型方法重载常规中的另一个方法具有相同的擦除打印(列表)示例抱歉。。。由于需要与Java 1.0保持向后兼容而产生的愚蠢规则
泛型类型信息随后会在一个名为类型擦除的过程中被删除,这实际上不是真的,因为方法保留了它们的完整签名。编译器如何验证对
print(List empList)
的调用?真正的原因是,当应用类型擦除时,结果必须是不同的。Java中的泛型是一种只使用语言的结构;它们仅在编译器中实现。运行时不知道泛型类型系统;泛型不是JVM的一部分。相反,泛型类和方法在编译期间通过称为类型擦除的过程进行转换。在此期间,编译器将使用原始版本替换所有泛型类型,并在使用该类型及其方法的客户端代码中适当插入强制转换/检查。编译器将如何选择单个实现?对于Java的类型擦除实际上是什么,您的知识非常有限且有偏差。唯一被删除的是附加到泛型类实例的类型参数。指定参数化类型的方法参数完全保留这些参数。您还自相矛盾:
编译器将如何获取单个实现?
——因为它是编译器,而不是运行时。或者你认为类型被删除了,以至于连编译器都看不见它们吗?你是对的@MarkoTopolnik(指定参数化类型的参数)。编译器错误出现了,Java语言规范排除了这种重载,因为遗留代码中的原始类型会产生冲突。这只是愚蠢的遗留问题困扰着我们,使泛型变得更不有用。如果这是真的,编译器类型将如何检查对
print(List)
?@MarkoTopolnik的调用,并在擦除之前进行检查。在运行时没有类型参数。您注意到这个问题在任何方面都不涉及运行时吗?这是一个关于编译器错误的问题。另外,在运行时甚至没有类型参数也不是真的。您可以考虑方法或字段的整个泛型签名。@MarkoTopolnik,编译正在准备运行时。在运行时没有类型参数,因此这两个方法将无法区分,因此这是一个编译错误,目的是禁止创建这种情况。在运行时,将已经选择了特定的方法。你知道吗?重载在编译时解决。这就是为什么可以从运行时安全地删除它们——只有它们不会被删除,并且您可以考虑此方法的整个泛型类型签名。