在 java 中通过三元运算符传递方法参数
Passing method argument through ternary operator in java
代码:
public class Foo {
static void test(String s){
System.out.println("String called");
}
static void test(int s){
System.out.println("int called");
}
public static void main(String[] args) throws Exception {
test(5>8? 5:8); // Line 1
test(5>8? "he":"ha"); // Line 2
test(5>8? 5:"ha"); // Line 3
System.out.println(5<8? 5:"ha"); //Line 4
}
}
当我执行此代码时,在 Line 3
处出现以下错误
Foo.java:24: error: no suitable method found for test(INT#1)
test(5>8? 5:"ha"); // Line 3
^
在三元运算符中使用类似的类型不会报错。但是使用不同的类型只会给方法调用 test(5>8? 5:"ha");
带来错误,但它适用于调用 System.out.println(5<8? 5:"ha");
当我添加另一个重载方法 static void test(Object s){}
时,//Line 3
会编译。
任何人都可以向我解释一下这种情况吗?
您在计算表达式之前调用方法。由于该方法没有 test(Object o) 的重载,因此它不起作用。
解析左侧表达式后调用该方法。
5>8?test(5):test("ha")
Java 中的每个表达式都有一个类型。 Java 语言规范中有一些复杂的规则,在 the conditional operator 部分告诉我们如何找到条件表达式的类型,例如 5 > 8 ? 5 : "ha"
。但简单来说,你总是得到第二个和第三个参数都是其成员的最具体的类型。
- 对于
5 > 8 ? 5 : 8
,5
和8
都是int
,所以整个表达式的类型是int
.
- 对于
5 > 8 ? "he" : "ha"
,"he"
和"ha"
都是String
,所以整个表达式的类型是String
.
- 对于
5 > 8 ? 5 : "ha"
,最适合5
和"ha"
的类型是Object
。所以整个表达式的类型为 Object
.
现在因为您有接受 int
和 String
的 test
版本,所以表达式 test ( 5 > 8 ? 5 : 8 )
和 test ( 5 > 8 ? "he" : "ha" )
都可以编译。
但是如果您没有接受 Object
的 test
版本,那么 test ( 5 > 8 ? 5 : "ha" )
无法编译。
这是过于简单化了。规则比我描述的要复杂得多,但这主要是因为它们考虑了涉及 null
操作数、自动装箱和自动拆箱的各种情况。
调用函数时
test(5>8? 5:8);
方法(在本例中)用于发送参数,因此括号内的所有内容都被视为参数,并且没有 appropriate/suitable 方法来处理此类调用(其参数应为 Object)当您在其中一个语句中评估 int 和 String 时。因此三元运算符不能在那里实现。
因此你可以使用这样的代码
(5 > 8) ? test(param1): test(param2);
或创建另一个接受 Object 作为参数的测试方法,然后评估该测试方法中的内容。像这样
void test(Object o){
//manipulate things here
}
代码:
public class Foo {
static void test(String s){
System.out.println("String called");
}
static void test(int s){
System.out.println("int called");
}
public static void main(String[] args) throws Exception {
test(5>8? 5:8); // Line 1
test(5>8? "he":"ha"); // Line 2
test(5>8? 5:"ha"); // Line 3
System.out.println(5<8? 5:"ha"); //Line 4
}
}
当我执行此代码时,在 Line 3
Foo.java:24: error: no suitable method found for test(INT#1)
test(5>8? 5:"ha"); // Line 3
^
在三元运算符中使用类似的类型不会报错。但是使用不同的类型只会给方法调用 test(5>8? 5:"ha");
带来错误,但它适用于调用 System.out.println(5<8? 5:"ha");
当我添加另一个重载方法 static void test(Object s){}
时,//Line 3
会编译。
任何人都可以向我解释一下这种情况吗?
您在计算表达式之前调用方法。由于该方法没有 test(Object o) 的重载,因此它不起作用。
解析左侧表达式后调用该方法。
5>8?test(5):test("ha")
Java 中的每个表达式都有一个类型。 Java 语言规范中有一些复杂的规则,在 the conditional operator 部分告诉我们如何找到条件表达式的类型,例如 5 > 8 ? 5 : "ha"
。但简单来说,你总是得到第二个和第三个参数都是其成员的最具体的类型。
- 对于
5 > 8 ? 5 : 8
,5
和8
都是int
,所以整个表达式的类型是int
. - 对于
5 > 8 ? "he" : "ha"
,"he"
和"ha"
都是String
,所以整个表达式的类型是String
. - 对于
5 > 8 ? 5 : "ha"
,最适合5
和"ha"
的类型是Object
。所以整个表达式的类型为Object
.
现在因为您有接受 int
和 String
的 test
版本,所以表达式 test ( 5 > 8 ? 5 : 8 )
和 test ( 5 > 8 ? "he" : "ha" )
都可以编译。
但是如果您没有接受 Object
的 test
版本,那么 test ( 5 > 8 ? 5 : "ha" )
无法编译。
这是过于简单化了。规则比我描述的要复杂得多,但这主要是因为它们考虑了涉及 null
操作数、自动装箱和自动拆箱的各种情况。
调用函数时
test(5>8? 5:8);
方法(在本例中)用于发送参数,因此括号内的所有内容都被视为参数,并且没有 appropriate/suitable 方法来处理此类调用(其参数应为 Object)当您在其中一个语句中评估 int 和 String 时。因此三元运算符不能在那里实现。
因此你可以使用这样的代码
(5 > 8) ? test(param1): test(param2);
或创建另一个接受 Object 作为参数的测试方法,然后评估该测试方法中的内容。像这样
void test(Object o){
//manipulate things here
}