Обобщения Java с классом и вложенным статическим интерфейсом - PullRequest
8 голосов
/ 06 марта 2011

Я хочу использовать универсальный класс внутри вложенного статического интерфейса.Моя цель - сделать что-то вроде этого:

public class MyClass<T>{
    private MyInterface task;

    public static interface MyInterface{
        void aMethod (T item);
    }
}

Но я получаю ошибку: не могу сделать статическую ссылку на нестатический тип T. Если я сделаю некоторые изменения (ниже), я могу использовать универсальныйвведите внутри интерфейса, но я хочу избежать этого метода, потому что избыточно писать один и тот же класс 2 раза: один для MyClass и один для MyInterface.

public class MyClass<T>{
    private MyInterface<T> task;

    public static interface MyInterface<T>{
        void aMethod (T item);
    }
}

Спасибо. РЕДАКТИРОВАТЬ : Я хочу сделать это:

MyClass c = new MyClass<String> ();
c.setInterface (new MyClass.MyInterface (){
    @Override
    public void aMethod (String s){
        ...
    }
);

или

MyClass c = new MyClass<AnotherClass> ();
c.setInterface (new MyClass.MyInterface (){
    @Override
    public void aMethod (AnotherClass s){
        ...
    }
);

Ответы [ 2 ]

17 голосов
/ 06 марта 2011

Статический вложенный класс или вложенный интерфейс (который, между прочим, всегда является статическим) не имеет никакого отношения к своему внешнему классу (или интерфейсу), кроме вложенности пространства имен и доступа к закрытым переменным.Параметр type внешнего класса недоступен внутри вложенного интерфейса в вашем случае, вы должны определить его снова. Чтобы избежать путаницы, я рекомендую использовать другое имя для этого внутреннего параметра.

(В качестве примера в стандартном API ищите интерфейс Map.Entry<K,V>, вложенный в интерфейс Map<K,V>, но не имеет доступа к его параметрам типа и должен объявить их снова.)

7 голосов
/ 06 марта 2011

Это не избыточно.Со статическим интерфейсом:

MyClass.MyInterface<String> myInstance;

и нестатическим классом innter (интерфейс всегда статичен):

MyClass<String>.MyInterface myInstance;

Более реальный пример:

Map<String, Integer> map = ...;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
    ...
}

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

class ClassWithAReallyLongName<T> {
    static interface Entry<T> {
    }
}

и

import my.package.ClassWithAReallyLongName.Entry;

class Foo {
    Entry<String> bar;
}

, хотя следует использовать эту идиомус осторожностью, чтобы не запутать читателя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...