Обновление Java 8 вызывает ошибку компилятора с унаследованным статическим перечислением

Мы обновляем проект Java 6 до Java 8. Повторная компиляция с Java 8 дает ошибки в подклассе java.awt.Frame, я упрощен к следующему:

орг/пример/Foo.java

package org.example;

import org.example.Type;
import java.awt.Frame;

public class Foo extends Frame {
    public Foo() {
        System.out.println(Type.BAZ);  // <=== error here, BAZ cannot be resolved
    }
}

орг/пример/Type.java

package org.example;

public class Type {
    public static final int BAZ = 1;
}

То, что, похоже, происходит, - это статическое перечисление java.awt.Window.Type, введенное в Java 7, имеет приоритет, даже если есть импорт для org.example.Type. Правильно ли это?

Означает ли это, что нам придется полностью квалифицировать все ссылки на наш тип с помощью org.example.Type?

Ответ 1

То, что, похоже, происходит, - это статический enum java.awt.Window.Type, введенный в Java 7, имеет приоритет, хотя есть импорт для org.example.Type. Правильно ли это?

Да. Класс Type является новым, но поведение не является. Это по дизайну и не нова для Java 8.

Означает ли это, что нам придется полностью квалифицировать все ссылки на наш тип с помощью org.example.Type?

Да, если вы расширяете класс, содержащий элемент Type.

Я бы поставил под вопрос, почему вы расширяете Frame, хотя: в большинстве случаев люди расширяют Frame или JFrame, их не должно быть. Благодарите композицию над наследованием и все такое.

Другим подходом может быть использование статического импорта для специфического импорта членов Type, в данном случае BAZ. что-то вроде этого:

package org.example;

import static org.example.Type.BAZ;
import java.awt.Frame;
public class Foo extends Frame {
   public Foo() {
      System.out.println(BAZ);  
   }
}

Это будет боль в шее, если Type имеет кучу участников. Еще один подход может заключаться в том, чтобы сделать Type интерфейс, а затем реализовать Foo этот интерфейс:

public interface Type {
    public static final int BAZ = 1;
}
public class Foo extends Frame implements Type{
    public Foo() {
        System.out.println(BAZ);  
    }
}

Вы также можете создать экземпляр Type в своем классе Foo или переименовать Type, чтобы избежать конфликта, или создать мост между Foo и Type.

Это все немного хакерские решения, которые просто не расширяют Frame.