Ошибка компиляции на Java 7 Diamond Operator: ArrayList();


У меня есть такая строка кода:

List<IObserver<?>> observers = new ArrayList<>();

И получаем 3 следующие ошибки:

Cannot instantiate the type ArrayList<?>
Syntax error on token "<", ? expected after this token
Type mismatch: cannot convert from ArrayList<?> to List<IObserver<?>>

Я использую Eclipse 3.7, я установил JDK 7 update 5, и проект настроен на использование системной библиотеки JRE[JavaSE1. 7] в пути сборки.

Переход в IObserver<?> с правой стороны компилирует нормально, но я должен использовать алмазный оператор.

Я думаю, что это проблема конфигурации, но я не могу понять, что я пропустил.

2 2

2 ответа:

Код должен работать: алмазный оператор используется правильно. Я предлагаю вам установить более свежую версию Eclipse (Indigo или Juno) и установить уровень соответствия компилятора 1.7.

Вот простой рабочий пример (здесь изобретен IObserver). Выведите на консоль: "нас 2"

package it.ant.test;

import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        List<IObserver<?>> observers = new ArrayList<>();
        IObserver<String> stringObserver = new Observer<>();
        IObserver<Integer> integerObserver = new Observer<>();
        stringObserver.addObserved("we are ");
        integerObserver.addObserved(2);

        observers.add(stringObserver);
        observers.add(integerObserver);

        for (IObserver<?> o : observers) {
            System.out.print(o.getObserved());
        }

    }
}

interface IObserver<T> {    
    void addObserved(T t);
    T getObserved();
}

class Observer<T> implements IObserver<T> { 
    private T observed;

    @Override
    public void addObserved(T observed) {
        this.observed = observed;

    }

    @Override
    public T getObserved() {
        return observed;
    }
}

Оператор Diamond будет работать только тогда, когда у вас нет wildcard в качестве универсального типа в вашем LHS..

List<IObserver<?>> observers = new ArrayList<>();

В этом коде компилятор видит LHS и удовлетворяется тем, что он может быть List из IObserver из anytype..

Но во время выполнения вам нужно иметь фактический тип для этого anytype..

Если бы вы не использовали Wildcard на LHS, это сработало бы.. На самом деле ваш приведенный выше код эквивалентен (если мы видим его как до Java 7): -

List<IObserver<?>> observers = new ArrayList<IObserver<?>>();

Как выводится общий тип RHS из ЛСЗ..Теперь вы понимаете, в чем проблема?? У вас нет Concrete Type, чтобы сделать object из IObserver на RHS..