benz
benz

Reputation: 4629

Interface ambiguously inherited fields

I am going through JLS section 9.3.1 and i came across an interesting concept of ambigious inherited fields. This is the example from JLS

interface BaseColors {
int RED = 1, GREEN = 2, BLUE = 4;
}
interface RainbowColors extends BaseColors {
int YELLOW = 3, ORANGE = 5, INDIGO = 6, VIOLET = 7;
}
interface PrintColors extends BaseColors {
int YELLOW = 8, CYAN = 16, MAGENTA = 32;
}
interface LotsOfColors extends RainbowColors, PrintColors {
int FUCHSIA = 17, VERMILION = 43, CHARTREUSE = RED+90;
}

It is allowing to have ambiguous fields inherited. But when i try to reference the field and access it, it gives compile time error. Giving a compile time error for ambigious fields. My question is, at first point why the compiler didn't complain when the ambigious field was inherited. Why at access time, it's giving this issue? If we do the same when using classes., It allows. Why not in case of interfaces. My point is it shouldn't allow at the first instant only. Clarification on this concept will be pretty helpful.

Upvotes: 12

Views: 1701

Answers (2)

JB Nizet
JB Nizet

Reputation: 692231

Interface fields are implicitely static final. And static fields are never inherited. You can hide a field by defining a new field with the same name, but you just need to qualify the field name with the appropriate interface to resolve the conflict:

PrintColors.YELLOW

or

RainbowCOlors.YELLOW

EDIT:

To clarify (hopefully):

The compiler allows you to use LotsOfColors.MAGENTA in the source code, although the field is actually defined in PrintColors.MAGENTA. But that's only to make your life a bit easier, especially when you reference a field from a superclass in a subclass.

In the byte-code, though, the compiler replaces the reference to LotsOfColors.MAGENTA by a reference to PrintColors.MAGENTA. It all happens at compilation time, and not at runtime like for polymorphic methods.

When you have an ambiguity (like for LotsOfColors.YELLOW), the compiler can't decide which of the fields you actually want to use. It can be PrintColors.YELLOW or RainbowColors.YELLOW. So, instead of taking an arbitrary decision, the compiler produces a compilation error, to force you to resolve the ambiguity. And you resolve the ambiguity in the source code by providing the actual class name, either PrintColors.YELLOW or RainbowColors.YELLOW.

Upvotes: 9

Jigar Joshi
Jigar Joshi

Reputation: 240996

Fields in interface are by default public static final so they won't get inherited

Upvotes: 7

Related Questions