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!
In interfaces methods are public abstract
by default. fields are public static final
the reason you can use the method is that the interface is package local. Try making it public.
However I am not able to use MyInterface at all, which I understand as it is package-private to custompackage.package1.
The interface is package-private, but all methods (and fields) are (implicitly or explicit) public.
it seems like MyEnum got the myMethod() method added, but it does not implement (from the outside) MyInterface.
MyEnum
has a public method called myMethod()
, regardless of whether it inherited the (public) abstract method from the interface or whether it declared the method itself. Said another way, even if the outside cannot see the interface, the outside can certainly see MyEnum
and see MyEnum.myMethod()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With