В Java 8, если у меня есть два интерфейса с разными (но совместимыми) типами возврата, отражение говорит мне, что один из двух методов - это метод по умолчанию, хотя я и не объявил метод по умолчанию или предоставил тело метода.
Например, возьмите следующий фрагмент кода:
package com.company;
import java.lang.reflect.Method;
interface BarInterface {}
class Bar implements BarInterface {}
interface FooInterface {
public BarInterface getBar();
}
interface FooInterface2 extends FooInterface {
public Bar getBar();
}
class Foo implements FooInterface2 {
public Bar getBar(){
throw new UnsupportedOperationException();
}
}
public class Main {
public static void main(String[] args) {
for(Method m : FooInterface2.class.getMethods()){
System.out.println(m);
}
}
}
Java 1.8 выводит следующий результат:
public abstract com.company.Bar com.company.FooInterface2.getBar()
public default com.company.BarInterface com.company.FooInterface2.getBar()
Это кажется странным не только потому, что оба метода присутствуют, но также потому, что один из методов внезапно и необъяснимо стал методом по умолчанию.
Запуск того же кода в Java 7 дает нечто менее неожиданное, хотя и все еще запутанное, учитывая, что оба метода имеют одну и ту же подпись:
public abstract com.company.Bar com.company.FooInterface2.getBar()
public abstract com.company.BarInterface com.company.FooInterface.getBar()
Java определенно не поддерживает несколько типов возврата, поэтому этот результат все еще довольно странный.
Очевидная следующая мысль: "Хорошо, возможно, это особенное поведение, которое применяется только к интерфейсам, потому что эти методы не имеют реализации".
Неправильно.
class Foo2 implements FooInterface2 {
public Bar getBar(){
throw new UnsupportedOperationException();
}
}
public class Main {
public static void main(String[] args) {
for(Method m : Foo2.class.getMethods()){
System.out.println(m);
}
}
}
дает
public com.company.Bar com.company.Foo2.getBar()
public com.company.BarInterface com.company.Foo2.getBar()
Что здесь происходит? Почему Java перечисляет их как отдельные методы и как один из методов интерфейса стал стандартным методом без реализации?