Для Java, как убедиться, что внутренний интерфейс и внешний интерфейс имеют один и тот же универсальный тип? - PullRequest
5 голосов
/ 16 февраля 2011

Версия 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);
    }
}

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

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){}

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

Ответы [ 4 ]

4 голосов
/ 16 февраля 2011

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

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

3 голосов
/ 16 февраля 2011

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

Согласно JLS;

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

1 голос
/ 16 февраля 2011

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

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

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

0 голосов
/ 01 июня 2012

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

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
   }

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