private void f(int a) { /* ... */ }
private void f(int a, int... b) { /* ... */ }
f(12); // calls the former? I would expect it to
f(12, (int[])null); // calls latter, but passes null for b?
// Can I force the compiler to call the second method in the same fashion
// as would happen if the first method didn't exist?
interface A {}
class B implements A {}
class C implements A {}
private void f(A a) {}
private void f(B b) {}
f(new C()); // calls the first method
f(new B()); // calls the second method?
f((A)(new B()); // calls the first method using a B object?
这是两个示例,但是作为代码阅读器,我更喜欢一个用于解决此问题的精确有序规则的规范列表,因为我经常没有时间设置构建环境来检查编译器正在做什么。
重载与重写
方法的正确实现的选择是在运行时完成的,正如您所指出的,现在要调用的方法的签名是在编译时决定的。
在编译时重载方法选择
通常,如果varargs方法与其他候选方法竞争,它们是最后选择的方法,因为它们被认为比接收相同参数类型的方法更不特定。
要验证它的编译时性质,可以进行以下测试。
声明一个类似的类并编译它(即javac chooseMethod.java
)。
public class ChooseMethod {
public void doSomething(Number n){
System.out.println("Number");
}
}
声明第二个类,调用第一个类的方法并编译它(即javac methodchooser.java
)。
public class MethodChooser {
public static void main(String[] args) {
ChooseMethod m = new ChooseMethod();
m.doSomething(10);
}
}
如果运行该程序(即Java MethodChooser
),则输出为Number
。
现在,向ChooseMethod
类添加第二个更具体的重载方法,并重新编译它(但不要重新编译另一个类)。
public void doSomething(Integer i) {
System.out.println("Integer");
}
如果再次运行main,输出仍然是number
。
基本上,因为它是在编译时决定的。如果重新编译MethodChooser
类(带有main的类),并再次运行该程序,输出将是Integer
。
因此,如果要强制选择重载方法之一,则参数的类型必须与编译时的参数类型相对应,而不仅仅是在运行时。
在运行时重写方法选择
public class ChooseMethodA {
public void doSomething(Number n){
System.out.println("Number A");
}
}
然后声明第二个扩展类并编译:
public class ChooseMethodB extends ChooseMethodA { }
在MethodChooser类中,您可以执行以下操作:
public class MethodChooser {
public static void main(String[] args) {
ChooseMethodA m = new ChooseMethodB();
m.doSomething(10);
}
}
如果运行它,将得到输出编号A
,这是可以的,因为该方法在ChooseMethodb
中没有被重写,因此调用的实现是ChooseMethoda
的实现。
现在,在methodchooserb
中添加一个重写的方法:
public void doSomething(Number n){
System.out.println("Number B");
}
重新编译这个方法,然后再次运行main方法。
现在,您将得到输出编号b
问题内容: 我之所以学习,是因为我参加了考试,而大多数Java并没有很多问题,但是我偶然发现了一个我无法解释的规则。这是一个代码片段: 返回: 1 3 1 3 虽然我希望它会返回: 1 3 1 4 为什么a2的类型确定在AX中调用哪种方法? 我一直在阅读有关重载规则和继承的文章,但这似乎晦涩难懂,以至于我无法找到确切的规则。任何帮助将不胜感激。 问题答案: 这些方法调用的行为由Java语言规范(参
运算符重载是通过函数重载实现的,概念上大家都很容易理解,这节我们来说一下运算符重载的注意事项。 1) 并不是所有的运算符都可以重载。能够重载的运算符包括: + - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= << >> <<= >>= == != <= >= && || ++ -- ,
当我运行这段代码时,它会打印。我的问题是为什么没有编译时错误?对象和字符串的默认值为NULL。那么为什么不编译器说。
Java 允许同一个类中定义多个同名方法,只要它们的形参列表不同即可。 如果同一个类中包含了两个或两个以上方法名相同的方法,但形参列表不同,这种情况被称为方法重载(overload)。 例如,在 JDK 的 java.io.PrintStream 中定义了十多个同名的 println() 方法。 这些方法完成的功能类似,都是格式化输出。根据参数的不同来区分它们,以进行不同的格式化处理和输出。它们之
dml2select Description:将数据库更新请求转换为只读查询请求,便于执行EXPLAIN Original: DELETE FROM film WHERE length > 100 Suggest: select * from film where length > 100 star2columns Description:为SELECT *补全表的列信息 Original:
问题内容: 假设我在课堂上说两种方法 和 那是什么感觉 重载还是重载? 问题答案: 重载是指两个或多个具有相同名称但参数不同的方法,就像您的示例一样。重载是从接口或抽象类实现一个方法的,因此超类中的方法具有实现,而子类中的方法具有不同的实现,它们仍然具有相同的方法名称和参数。