Интерфейс неоднозначно унаследованных полей

Я просматриваю раздел JLS 9.3.1, и я столкнулся с интересной концепцией неоднозначных унаследованных полей. Это пример из 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;
}

Это позволяет наследовать неоднозначные поля. Но когда я пытаюсь ссылаться на поле и получать доступ к нему, он дает ошибку времени компиляции. Предоставление ошибки времени компиляции для неоднозначных полей. Мой вопрос, в первую очередь, почему компилятор не жаловался, когда неоднозначное поле было унаследовано. Почему во время доступа он дает эту проблему? Если мы делаем то же самое при использовании классов., Это позволяет. Почему бы и нет в случае интерфейсов. Я хочу сказать, что он не должен допускать только в первый момент. Разъяснение этой концепции будет весьма полезным.

Ответ 1

Поля интерфейса неявно статичны. И статические поля никогда не унаследованы. Вы можете скрыть поле, указав новое поле с тем же именем, но вам просто нужно определить имя поля с соответствующим интерфейсом для разрешения конфликта:

PrintColors.YELLOW

или

RainbowCOlors.YELLOW

EDIT:

Чтобы уточнить (надеюсь):

Компилятор позволяет использовать LotsOfColors.MAGENTA в исходном коде, хотя поле фактически определено в PrintColors.MAGENTA. Но это только для того, чтобы сделать вашу жизнь немного легче, особенно когда вы ссылаетесь на поле из суперкласса в подклассе.

В байтовом коде компилятор заменяет ссылку на LotsOfColors.MAGENTA ссылкой на PrintColors.MAGENTA. Все это происходит во время компиляции, а не во время выполнения, как для полиморфных методов.

Если у вас двусмысленность (например, для LotsOfColors.YELLOW), компилятор не может решить, какое из полей вы хотите использовать. Это может быть PrintColors.YELLOW или RainbowColors.YELLOW. Таким образом, вместо принятия произвольного решения компилятор создает ошибку компиляции, чтобы заставить вас разрешить двусмысленность. И вы разрешите двусмысленность в исходном коде, указав фактическое имя класса: PrintColors.YELLOW или RainbowColors.YELLOW.

Ответ 2

Поля в интерфейсе по умолчанию public static final, поэтому они не будут наследоваться