Версия 1

public interface Outer<T>{
    public interface Inner<T>{
        T get();
        void set(T t);
    }
}

Несмотря на одинаковый синтаксис универсального типа, эти два типа полностью независимы.

Версия 2

public interface Outer<T>{
    public interface Inner<V extends T>{
        V get();
        void set(V t);
    }
}

Получил ошибку: "Невозможно сделать статическую ссылку на нестатический тип T"

Версия 3

public interface Outer<T>{
    public interface Inner{
       <T> T get();
       <T> void set(T m);
    }
}

Не уверен, что это то, что я хочу, но кажется, что все в порядке (в eclipse нет ошибок), поэтому я пытаюсь реализовать это:

public Test implements interface Outer.Inner {
       //no problem in these two
       <T> T get(){..};
       <T> void set(T m){...};

        //Errors come up here:
       Map<String,T> map;
       public Test(Map<String,T> map){
            this.map=map
       }

}

Появляется ошибка: «T не может быть разрешен к типу» в обоих

  1. декларация Map<String,T> map
  2. аргумент конструктора public Test(Map<String,T> map){}

Итак, как я могу решить эту проблему?

5
Alex Luya 16 Фев 2011 в 10:53
Проблема в версии 3 заключается в том, что вы используете тип T, даже не указывая, что это за тип.
 – 
Ken Wayne VanderLinde
16 Фев 2011 в 11:06
Не вставляйте HTML в качестве содержания вашего вопроса. Используйте встроенные возможности форматирования.
 – 
Grzegorz Oledzki
16 Фев 2011 в 11:30
Изменен формат вопроса на уценку
 – 
Sean Patrick Floyd
16 Фев 2011 в 11:41

4 ответа

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

Согласно JLS;

9.5 Объявления типов членов
Интерфейсы могут содержать тип члена декларации (§8.5). Тип члена объявление в интерфейсе неявно статический и общедоступный

3
Gursel Koca 16 Фев 2011 в 11:26

Что вам следует сделать, так это, возможно, иметь Inner extends Outer, если тип должен быть обязательно применен, но, конечно, вам придется реализовать методы как Inner, так и Outer. Я не уверен, что ты этого хочешь.

interface Outer<T> {
  interface Inner<T> extends Outer<T> {
    T myMethod(T t);
  }
}

На самом деле нет другого способа обеспечить то, что вы хотите. Причина в том, что интерфейс всегда статичен. Кроме того, вы действительно не хотите/не нуждаетесь в таком поведении: интерфейс уже достаточно гибок для вас. Просто узнайте, где вы можете контролировать это, и мир будет вашим!

1
Olivier Grégoire 16 Фев 2011 в 11:47

Ошибка в реализации - вы забыли добавить универсальный тип, это должно помочь:

public class Test<T> implements interface Outer<T>.Inner {

   T get(){..};
   void set(T m){...};

    //Errors come up here:
   Map<String,T> map;
   public Test(Map<String,T> map){
        this.map=map
   }

}
0
alexey28 1 Июн 2012 в 13:35

Во-первых, сделать это никак нельзя, так как внешний интерфейс — не что иное, как «пространство имен» для внутреннего интерфейса. Им действительно больше нечего делать друг с другом.

Возникает вопрос: зачем вам такой контроль над вещами? Если в классе, реализующем интерфейс, будет решено, что использование одного и того же типа имеет смысл, то так и будет для этого класса. Но другая реализация может и должна иметь право выбирать иное. Это особенно верно, поскольку классы, реализующие Outer, и те, которые реализуют Inner, не ограничены вложением друг в друга.

4
Ken Wayne VanderLinde 16 Фев 2011 в 11:11