2016-07-28 5 views
3

Рассмотрим следующий общий класс Base<ID> с нестационарным внутренним классом.Почему компилятор Eclipse Java жалуется на неконтролируемый отбор для внутренних производных типов?

public class Base<ID> { 
    ID id; 

    public Base(ID id) { 
    this.id = id; 
    } 

    public ID getId() { 
    return id; 
    } 

    protected class BaseInner { 
    String text = "Inner"; 
    } 

    protected void method(BaseInner o) { 
    o.text = "Foo"; 
    } 
} 

Метод Base.method принимает аргумент типа BaseInner. Теперь рассмотрим следующие производные классы.

public class Sub<ID> extends Base<ID> { 
    public Sub(ID id) { 
    super(id); 
    } 

    @Override 
    protected void method(BaseInner o) { 

    if (o instanceof Sub.SubInner) { 
     SubInner sub = (SubInner) o; // Why does this cast emit an "unchecked cast" warning 

     sub.text = "Bar"; 
     sub.value = 1337; 
    } 
    } 

    protected class SubInner extends BaseInner { 
    Number value = 42; 
    } 
} 

Класс Sub происходит от Base и внутренний класс SubInner вытекает из внутреннего класса BaseInner. Параметр общего типа ID из Sub передается как аргумент типа базовому классу Base.

Мой вопрос: Почему компилятор жалуется на отлитого из BaseInner к SubInner в наиважнейшей method из Sub?

Чтобы понять это предупреждение, я попытался построить прецедент, в котором вызывается method с некоторым Sub<B>.SubInner, что оправдывает предупреждение. Но все, что я могу придумать (включаяи ? super), выдает ошибку компилятора при вызове метода, если типы несовместимы.

Так что, я думаю, нет никаких оснований для предупреждения о неконтролированном литье в method. Я что-то пропустил?

Как переопределение метода происходит в реализации Sub<ID>, компилятор способен вычесть общий тип SubInner в Sub<ID>.SubInner. Так что вопрос не дубликат!

предупреждения компилятора

Затмения

Тип безопасность: Переполнение отлито из базы < ID> .BaseInner к югу < ID> .SubInner

Варинг не меняет ни, если я не использовать Base<ID>.BaseInner как параметр метода, и если я использую Sub<ID>.SubInner в выраженном выражении.

+2

Просто догадаться, но поскольку вы используете 'o instanceof Sub.SubInner' в инструкции if, вы не должны использовать' Sub.SubInner' в следующем выражении? – nbro

+0

Я уже пробовал это, а также используя 'Sub .SubInner' в роли, но он всегда вызывает то же предупреждение. – niks

+1

Какой компилятор вы используете? Я не получаю никаких предупреждений с javac 8. – assylias

ответ

0

В этой ситуации неконтролируемый литой означает, что вы производите от неквалифицированного типа до родового типа.

Set<String> set = new HashSet(); 

Эта строка также выдаст предупреждение о непроверенной задаче.

Это предупреждение возникает из-за того, что компилятор не может вычитать, является ли бросок безопасным во время компиляции.

Экземпляр SubInner имеет ссылку на Sub-экземпляр. Вы кастинг из Base.BaseInner, так что вы также отбрасываете от Base to Sub < ID>. Поэтому у вас есть это предупреждение.

Редактировать

Решение заключается в использовании общего параметра.

public class Base<ID> { 
    ID id; 

    public Base(ID id) { 
     this.id = id; 
    } 

    public ID getId() { 
     return id; 
    } 

    protected class BaseInner { 
     String text = "Inner"; 
    } 

    protected void method(Base<ID>.BaseInner o) { 
     o.text = "Foo"; 
    } 
} 


public class Sub<ID> extends Base<ID> { 
    public Sub(ID id) { 
     super(id); 
    } 

    @Override 
    protected void method(Base<ID>.BaseInner o) { 
     SubInner sub = (SubInner) o; 
     sub.text = "Bar"; 
     sub.value = 1337; 
    } 

    protected class SubInner extends BaseInner { 
     Number value = 42; 
    } 
} 
+0

«Эта строка также выдаст предупреждение о непроверенной броске». Нет, это приведет к предупреждению о необработанных типах. Там нет броска. –

+0

Да, вы правы –

+0

Я уже пытался добавить аргументы общего типа в SubInner и к методу без успеха. – niks

1

Этот шов является проблемой компилятора Eclipse.

Компилятор Oracle (javac) не содержит никаких предупреждений.

 Смежные вопросы

  • Нет связанных вопросов^_^