In Java 8, if I have two interfaces with different (but compatible) return types, reflection tells me that one of the two methods is a default method, even though I haven't actually declared the method as default or provided a method body.
For instance, take the following code snippet:
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 produces the following output:
public abstract com.company.Bar com.company.FooInterface2.getBar()
public default com.company.BarInterface com.company.FooInterface2.getBar()
This seems odd, not only because both methods are present, but also because one of the methods has suddenly and inexplicably become a default method.
Running the same code in Java 7 yields something a little less unexpected, albeit still confusing, given that both methods have the same signature:
public abstract com.company.Bar com.company.FooInterface2.getBar()
public abstract com.company.BarInterface com.company.FooInterface.getBar()
Java definitely doesn't support multiple return types, so this result is still pretty strange.
The obvious next thought is: "Okay, so maybe this is a special behavior that only applies to interfaces, because these methods have no implementation."
Wrong.
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);
}
}
}
yields
public com.company.Bar com.company.Foo2.getBar()
public com.company.BarInterface com.company.Foo2.getBar()
What's going on here? Why is Java enumerating these as separate methods, and how has one of the interface methods managed to become a default method with no implementation?