java Java名称冲突,具有相同的擦除,不隐藏另一个

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14002965/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 14:42:32  来源:igfitidea点击:

Java name clash, have the same erasure, neither hides the other

javagenericsname-clash

提问by user506246

I am getting this name clash error and i don't know how should i solve the problem. I have two classes and i am using overloaded method "createSensors". To simplify here is the code that generates the problem:

我收到此名称冲突错误,我不知道应该如何解决该问题。我有两个类,我正在使用重载方法“createSensors”。为了简化这里是产生问题的代码:

public abstract class ClassA {
    public static List<Sensor> createSensors(Collection<? extends ClassA> list) {
        List<Sensor> sensors = new ArrayList<Sensor>();
        for (ClassA s : list) {
           sensors.add(s.getSensor());
        }
        return sensors;
    }
}

public abstract class ClassB extends ClassA {
    public static List<Sensor> createSensors(Collection<? extends ClassB> list) {
        List<Sensor> sensors = new ArrayList<Sensor>();
        for (ClassB s : list) {
           sensors.add(s.getSensor());
        }
        return sensors;
   }
}

采纳答案by Tom Hawtin - tackline

The general solution is to use different names. These methods could be in classes without an inheritance relationship as these are not instance methods.

一般的解决方案是使用不同的名称。这些方法可以在没有继承关系的类中,因为它们不是实例方法。

As pointed out, the method implementation in the question are the same (typo excepted).

正如所指出的,问题中的方法实现是相同的(错别字除外)。

(This issue with overloading is often confused with erasure of runtime types. Overloading is a link-time rather than a dynamic issue, so could be easily fixed in the language. It's just not a particularly useful change, and not a good idea to encourage overloading.)

(这个重载问题经常与运行时类型的擦除混淆。重载是一个链接时而不是一个动态问题,所以可以很容易地在语言中修复。这不是一个特别有用的改变,也不是一个鼓励的好主意超载。)

回答by Ar3s

General answer :

一般回答:

Apart from the problem of the same implementation here, the core of the problem is that, somewhat barbaric, "method A and Method B have the same erasure".

除了这里实现相同的问题,问题的核心是,有点野蛮,“方法A和方法B具有相同的擦除”。

What makes it a complicated question is that we generally don't (at least I did not this very morning) know a lot about "Type Erasure".

使它成为一个复杂问题的原因是我们通常(至少今天早上我没有)对“类型擦除”了解很多。

To make it short :

简而言之:

Parametric types perform type check at compile time (to ensure type correctness) but forget their type parameters at runtime (to avoid the generation of underlying methods).

参数类型在编译时执行类型检查(以确保类型正确)但在运行时忘记它们的类型参数(以避免生成底层方法)。

This sounds at the same time simple and puzzling. Best way to understand it is to refer to the following literature :

这听起来既简单又令人费解。理解它的最佳方法是参考以下文献:

  1. What is a reifiable type ?
  2. How and under what conditions is erasure performed ?
  3. Have you any idea/examples about what it could imply in my coding life ?
  4. Well that's odd and I don't really like it but I'm curious why they did that ...
  1. 什么是可具体化的类型?
  2. 如何以及在什么条件下执行擦除?
  3. 你对它在我的编码生活中可能意味着什么有什么想法/例子吗?
  4. 嗯,这很奇怪,我不太喜欢它,但我很好奇他们为什么这样做......

Hope that'll help you as much as it helped me.

希望这对你有帮助,就像它对我的帮助一样。

Specific answer :

具体回答:

In your case

在你的情况下

public abstract class ClassA {
    public static List<Sensor> createSensors(Collection<? extends ClassA> list) {
        //do stuff
    }
}

public abstract class ClassB extends ClassA {
    public static List<Sensor> createSensors(Collection<? extends ClassB> list) {
        //do other stuff
   }
}

will be "transformed" by javac to

将被 javac“转换”为

public abstract class ClassA {
    public static List createSensors(Collection list) {
        //do stuff
    }
}

public abstract class ClassB extends ClassA {
    public static List createSensors(Collection list) {
        //do other stuff
   }
}

where one clearly can't override the other (not the same type parameter) but end up being exactly the same at runtime (no way for your program to choose which one to use).

其中一个显然不能覆盖另一个(不是相同的类型参数),但最终在运行时完全相同(您的程序无法选择使用哪个)。

Enough of this problem, how to solve it ? You may proceed with one of the following approach :

够了这个问题,如何解决它?您可以继续使用以下方法之一:

  • Use different names : createASensorsand createBSensorsthis approach is the most obvious but would seem a little less elegant.

  • Add a parameter : createSensors(Collection<? extends ClassA> list, ClassA typeDefiner)this approach can seem barbaric but is a little less elegant but is the one used in java.util.Listfor the method <T> T[] toArray(T[] a).

  • 使用不同的名称:createASensors而且createBSensors这种方式是最明显的,但似乎有点不太优雅。

  • 添加一个参数:createSensors(Collection<? extends ClassA> list, ClassA typeDefiner)这种方法看起来很野蛮,但不太优雅,但它是java.util.List用于该方法的方法<T> T[] toArray(T[] a)

回答by Asanka Siriwardena

Check the project setting and compiler version of the project. Right click on project --> Properties --> Java Compiler. Make sure compliance setting are up to date. I had this problem when compliance settings were set to 1.4 instead 1.6

检查项目的项目设置和编译器版本。右键单击项目 --> 属性 --> Java 编译器。确保合规性设置是最新的。当合规性设置设置为 1.4 而不是 1.6 时,我遇到了这个问题