gpt4 book ai didi

java - Java 中的模糊重载

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:27:52 25 4
gpt4 key购买 nike

我正在学习Java,遇到了一些关于重载的问题。以下面的函数使用为例:

f('a', 'a');

如果我们有两个定义:

static void f(int i, char j){
System.out.println("int_char");
}

static void f(double i, char j){
System.out.println("double_char");
}

会好的。因为所有的第二个参数都是完全匹配的。但是第一个参数,他们都用widen。 char 的扩展顺序是:

char -> int -> long -> float -> double

char要实现int,还需要一步。但要实现双倍,则需要4个步骤。所以结果是:

int_char

但是我将参数的顺序更改为:

static void f(int i, char j){
System.out.println("int_char");
}

static void f(char i, double j){
System.out.println("char_double");
}

编译器会提出一个不明确的错误。为什么?

另一种情况如下:

static void f(char i, Character j){
System.out.println("char_Character");
}

static void f(Character i, Character j){
System.out.println("Character_Character");
}

第二个参数都使用atuoboxing。但是 void f(char i, Character j) 的第一个参数是完全匹配的。为什么这两个函数放在一起会导致歧义?

最后,如果这些功能中的任何一个与以下功能一起出现:

static void f(Character... i){
System.out.println("Character_varargs");
}

输出不是 Character_varargs,因为 widen > boxing > varargs。但是当两个不明确的函数与 Character_varargs 一样时:

static void f(char i, Character j){
System.out.println("char_Character");
}

static void f(Character i, Character j){
System.out.println("Character_Character");
}

static void f(Character... i){
System.out.println("Character_varargs");
}

结果将是 Character_varargs。为什么?

甚至我们添加了一些无歧义和高优先级的重载函数,如:

static void f(int i, char j){
System.out.println("int_char");
}

static void f(char i, double j){
System.out.println("char_double");
}

static void f(int i, double j){
System.out.println("int_double");
}

static void f(Character... i){
System.out.println("Character_varargs");
}

结果仍然是 Character_varargs。为什么?如果只考虑void f(int i, double j)和void f(Character... i),输出应该是int_double。

当编译器遇到有歧义的函数时,它是否直接“跳转”到 varargs 函数(如果有)而不考虑任何其他候选函数?

谢谢!

最佳答案

Widen > boxing > varargs 不完全正确。

适当的是加宽>装箱和拆箱>加宽和装箱/拆箱和可变参数这三者。

在第三步中,所有三个都被允许。

static void f(int i, char j){
System.out.println("int_char");
}

static void f(double i, char j){
System.out.println("double_char");
}

在上述情况下,您可以根据 1 个特定 arg 的加宽距离按偏好顺序“排列”它们。但是下面你不能排列它们。

static void f(int i, char j){
System.out.println("int_char");
}

static void f(char i, double j){
System.out.println("char_double");
}

下一个问题是

static void f(char i, Character j){
System.out.println("char_Character");
}

static void f(Character i, Character j){
System.out.println("Character_Character");
}

当需要允许装箱进行匹配时(因为没有装箱就没有匹配),所有在第一个或第二个参数上使用或不使用装箱的方法都以相同的优先级对待。所以第一个并不比第二个好,所以我们不能按优先顺序排列它们。导致模棱两可。

现在如果下面也存在,

static void f(Character... i){
System.out.println("Character_varargs");
}

按照规则,由于在装箱/拆箱后没有找到合适的方法(发现了 2 个模棱两可的方法),所以第三步需要使用 var args。最终找到要解决的方法。


在下面的情况下,我们还需要转到第三步(加宽和装箱/拆箱和可变参数)来找到匹配项

static void f(int i, char j){
System.out.println("int_char");
}

static void f(char i, double j){
System.out.println("char_double");
}

static void f(int i, double j){
System.out.println("int_double");
}

static void f(Character... i){
System.out.println("Character_varargs");
}

引用https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12

关于java - Java 中的模糊重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19150776/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com