2013-05-20 4 views
7

Это вопрос chrertGeneric classes with Collection getter of other types. Если вы можете придумать лучшее название на мой вопрос, не стесняйтесь редактировать его:Необработанные типы с общими методами, не зависящими от общего типа

Следующий код содержит общий класс GenericClass<T> с методом обратного типа T и другой метод с возвращаемым типом Collection<String>, который, очевидно, не зависит от T.

Теперь, если я создаю необработанный GenericClass (чего я бы никогда не делал, поэтому этот вопрос является более теоретическим вопросом, чтобы понять, что происходит), тогда вызов этого метода в расширенном цикле не будет работать, потому что вся информация общего типа, похоже, теряется при использовании сырых типов. Но тогда, когда вы вызываете тот же самый метод в задании, он работает (он предупреждает о небезопасности типа, но компилирует).

С моей точки зрения, либо оба не должны работать, либо оба должны работать. Я не понимаю, почему один работает, а другой нет. Есть ли у вас какие-либо намеки или знаете какие-либо части JLS, которые объясняют это поведение?

public class GenericClass<T> { 

    T doSomething() { 
     return null; 
    } 

    Collection<String> getCollection() { 
     return Collections.emptyList(); 
    } 

    public static void main(String[] args) { 
     GenericClass raw = new GenericClass(); 
     // This will not compile (Error message below) 
     for (String str : raw.getCollection()) { 
      // Type mismatch: cannot convert from element type Object to String 
     } 
     // This is only a warning: 
     // Type safety: The expression of type Collection needs unchecked conversion to conform to Collection<String> 
     Collection<String> coll = raw.getCollection(); 
     for (String string : coll) { 
      // works just fine 
     } 
    } 
} 

Существует связанный с этим вопрос, который, вместе с принятым ответ здесь, объясняет, что происходит довольно хорошо: Why won't this generic java code compile?

ответ

4

В первом случае, raw.getCollection() возвращает сырье Collection. JLS 14.14.2 определяет тип проверки для улучшенного for цикла:

Если Тип (в производстве FormalParameter) является ссылочным типом, то TargetType является типом; в противном случае TargetType является верхней границей преобразования захвата аргумента типа I, или Object, если я необработан.

(курсив)

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

+0

Акцент и объяснение второго случая делают его совершенно ясным. Спасибо! – jlordo

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