I just came accross the following code, which surprised me a little bit, I converted it to a simple SSCEE here though:
custompackage.package1.MyEnum.java
public enum MyEnum implements MyInterface {
CONSTANT_ONE() {
@Override
public void myMethod() {
//do something very interesting
}
},
CONSTANT_TWO() {
@Override
public void myMethod() {
//do something very interesting
}
};
}
interface MyInterface {
void myMethod();
}
Now from outside this package, I can do the following:
Consumer<MyEnum> myMethod = MyEnum::myMethod;
However I am not able to use MyInterface
at all, which I understand as it is package-private to custompackage.package1
.
I don't understand what exactly is going on though, it seems like MyEnum
got the myMethod()
method added, but it does not implement (from the outside) MyInterface
.
How does this work?
Well you can't see MyInterface
from outside the package, as you said - but MyEnum
effectively has a public abstract myMethod()
method, which you're able to use as a method reference.
Leaving aside fancy new Java 8 features, this is valid (even outside the package):
// Even MyEnum x = null; will compile, but obviously fail
MyEnum x = MyEnum.CONSTANT_ONE;
x.myMethod();
The method is inherited from the interface, even though the interface itself is not visible.
This isn't specific to interfaces and enums, either. For example:
// Foo.java
package foo;
class SuperFoo {
public void publicMethod() {
}
}
public class Foo extends SuperFoo {
}
// Bar.java
package bar;
import foo.Foo;
public class Bar {
public void test() {
Foo foo = new Foo();
foo.publicMethod();
}
}
This compiles fine, even though Foo
doesn't even override publicMethod
. As far as Bar
is concerned, it's inherited from somewhere, but it doesn't know where!