【问题标题】:The method ambiguous for the type - Why not resolving类型不明确的方法 - 为什么不解决
【发布时间】:2014-04-02 22:03:34
【问题描述】:
public class Animal {}

public class Bird extends Animal {}

public class Mamal extends Animal {}

public class Human extends Mamal {}

public class Main {

    public void Hungry(Mamal mamal){
        System.out.println("Mammal");
    }   
    public void Hungry(Human human){
        System.out.println("Human");        
    }
    public void Hungry(Bird bird){
        System.out.println("Bird");
    }
    public static void main(String a[]){
        Main main = new Main();
        main.Hungry(null);
}

编译器说 Hungry(Mamal) 方法不明确。 我希望执行“人类”方法,因为它是最低级别。我没能从http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12找到模棱两可的原因

【问题讨论】:

  • " 我希望执行 "Human" 方法" 因为 null 什么时候是 Human 实例?
  • @Sergi:按照惯例,是的——但这不是语言规则的一部分,这就是这个问题的意义所在。
  • @m0skit0:null 文字可转换为任何类类型。
  • null 不是实例。这只是一个值。
  • 不要将您的方法名称大写。

标签: java


【解决方案1】:

HumanBird 在继承层次结构中处于同一级别(虽然不是视觉上的)。或者将它们视为完全不相关的引用类型。因此,一个并不比另一个更具体。

如果您删除 Hungry(Bird) 方法,您的代码将编译。

更具体的规则是here

一个名为 m 的固定数量成员方法比另一个更具体 如果满足以下所有条件,则具有相同名称和数量的成员方法 条件成立:

  • 第一个成员方法的参数声明类型为 T1,...,Tn。

  • 其他方法的参数声明类型为U1,..., 联合国。

  • 如果第二种方法是通用的,则令 R1 ... Rp (p ≥ 1) 为其 类型参数,令 Bl 为 Rl (1 ≤ l ≤ p) 的声明边界,令 A1 ... Ap 是为此推断的类型参数(§15.12.2.7) 在初始约束 Ti

  • 否则,令 Si = Ui (1 ≤ i ≤ n)。

  • 对于从 1 到 n 的所有 j,Tj <: sj.>

  • 如果第二种方法是如上所述的泛型方法,则 Al <: bl l p>

所以你有

public void Hungry(Human human){
    System.out.println("Human");        
}
public void Hungry(Bird bird){
    System.out.println("Bird");
}

所以HumanT1BirdU1(也尝试相反)。方法不是通用的。

S1 = U1

对于从 i 到 n(1 到 1)的所有 j,这应该成立:Ti &lt;: Si,其中 &lt;:

我们写 T <: s t>

这不适用于我们的两种方法,因为Human 不是Bird 的子类型,反之亦然,因此没有更具体的方法可以调用,即。模棱两可。

就像你有过一样

void method(String s){}
void method(RandomReferenceType t) {}

并试图打电话

method(null);

【讨论】:

  • @TedBigham Human 扩展了哺乳动物,因此被认为比哺乳动物更具体。
  • 我现在看到了。谢谢!
【解决方案2】:

混淆是因为您有三个同名的方法,并且您传递了一个空值。编译器不知道您正在调用哪个方法。只需写一个即public void hungry(Animal animal) 并检查里面的动物类型。例如if(animal instanceof Bird) { System.out.println("Bird") ....。 还将方法名称更改为小写。有时编译器会失败。

【讨论】:

    【解决方案3】:

    由于null 没有与之关联的类型,编译器不知道应该调用您的哪个hungry 方法;因此,它是“模棱两可的”。为了消除歧义,只需转换它:

    public class Main {
    
        public void hungry(Mamal mamal){
            System.out.println("Mammal");
        }   
        public void hungry(Human human){
            System.out.println("Human");        
        }
        public void hungry(Bird bird){
            System.out.println("Bird");
        }
        public static void main(String a[]){
            Main main = new Main();
            main.hungry((Mamal)null);
        }
    }
    
    class Animal {}
    class Bird extends Animal {}
    class Mamal extends Animal {}
    class Human extends Mamal {}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-13
      • 2010-10-17
      • 1970-01-01
      • 2020-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多