Почему и как этот код Java компилируется?
Следующий код печатает "String"
public class Riddle {
public static void main(String[] args) {
hello(null);
}
public static void hello(Object o) {
System.out.println("Object");
}
public static void hello(String s) {
System.out.println("String");
}
}
Почему этот код компилируется? Не является ли неопределенным двузначный?
Например, следующий код НЕ компилируется из-за неоднозначной подписи.
public class Riddle {
public static void main(String[] args) {
hello(null);
}
public static void hello(Object o) {
System.out.println("Object");
}
public static void hello(Integer o) {
System.out.println("Integer");
}
public static void hello(String s) {
System.out.println("String");
}
}
Может кто-нибудь объяснить, почему первый пример может скомпилироваться без двусмысленных ошибок?
Ответы
Ответ 1
Во втором случае компиляция не выполняется, поскольку компилятор не может решить между методом, который принимает Integer и метод, который принимает строку, где, как и в случае с первым, компилятор может понять это.
Ссылка: http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2
Ответ 2
пожалуйста, см. JLS §15.12.2
следующий порядок решения метода для назначения вызова важен когда такой же тип данных типа,
- (для примитивного типа данных) точное совпадение типа данных и вызов его. 1.1, если нет, тогда вызывается более широко, чем этот доступный тип данных, затем вызывайте его.
- для типа Wrapper типа Data или его родителя, если выше не удалось.
- Vararg этого типа данных будет соответствовать, если выше 2-неудачно.