【问题标题】:Why compiler thinks `byte...` and `char...` are ambigious [duplicate]为什么编译器认为`byte ...`和`char ...`模棱两可[重复]
【发布时间】:2019-01-09 20:48:13
【问题描述】:

关于方法签名中的 var-args 的类似问题被问了几次(1,2),但有一个极端情况我不明白。编译器可以区分int...和long...重载的方法签名,并调用较小类型的方法。

然而byte 和char 的大小显然不一样,但编译器抱怨test() 下面的方法不明确:

static void test(byte... v) { System.out.println("Byte"); }
static void test(char... v) { System.out.println("Char"); }

public static void main(String[] args) {
  test(); // Error:(7, 5) java: reference to test is ambiguous
          // both method test(byte...) in App and method test(char...) in App match
}

short... 和 char... 也是如此,但 int... 和 char... 并不模棱两可。

为什么 char... 与 byte... 或 short... 被认为是模棱两可的,而 byte... 和 short... 在方法签名中是可区分的?

static void test(byte... v) { System.out.println("Byte"); }
static void test(short... v) { System.out.println("Short"); }

public static void main(String[] args) {
  test(); // Byte
}

【问题讨论】:

  • 在您的示例中,您没有将参数传递给测试。编译器不知道你打算调用哪一个,因为它通常会从你传递给它的参数中推断出来。
  • int 可以隐式转换为 long,而 byte 和 char 彼此不兼容。主要是因为char和byte都是8位的,而char是无符号的。
  • @SotrisDelimanolis 如果您认为这是重复的,请指出答案,解释为什么 char... 不同。
  • stackoverflow.com/a/32293611/438154 byte 和 char 之间没有“更具体”的关系,而 int 和 char 之间有。
  • @Powerlord char 是 16 位无符号整数,而不是 8 位。

标签: java


【解决方案1】:

您没有在调用中包含 任何 参数,那么编译器如何知道类型?

还有 “否则,如果操作数是编译时类型 byte、short 或 char,则通过扩大的原始转换(第 5.1.2 节)将其提升为 int 类型的值。” https://docs.oracle.com/javase/specs/jls/se10/html/jls-5.html#jls-5.6 编译器不认为这些类型是等效的。它将他们提升为int。由于两种形式都升级为int,它不知道使用哪个。

尝试显式转换参数以解决歧义。

【讨论】:

  • 不,似乎char 与byte 和short 没有子类型关系,就像int 和long 所说的in this answer 和JLS 4.1 .
  • 您在我的答案中有链接,请自行检查。这似乎是与boolean... 相同的极端案例。如果你能解释和反驳我,我会接受你的回答。使用 char... 和 int... 有效,根据 JLS 4.10 和 4.11 存在子类型关系。
  • 我引用了 JLS。 “不”是什么意思?
  • 根据您的 JLS,如果 byte... 和 short... 都被提升为 int...,它将如何工作?这意味着方法签名不明确,但编译器根据我的回答选择了byte...。检查我的问题中的第二个示例,它打印Byte。
  • 如果您没有在参数列表中提供类型,或者如果您提供的类型匹配多个签名,则会产生歧义。在您的问题中,您没有在方法调用中显示任何类型信息。这意味着两个方法签名都是同样可能的候选者。
【解决方案2】:

test 函数已重载。您需要传递适当的参数,以便编译器可以推断要调用哪个方法。此外,byte 和 char 都是 varargs 的同等特定原语(我的意思是编译器对它们的处理方式相似),从而导致歧义。

【讨论】:

  • OP 代码中的意图是重载它。令人困惑的是,为什么重载有歧义。
猜你喜欢
  • 1970-01-01
  • 2021-11-28
  • 2014-12-10
  • 2011-06-25
  • 1970-01-01
  • 1970-01-01
  • 2011-04-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多