2013-02-13 2 views
1

Я пытаюсь построить простой интерфейс с использованием дженерик, вот код, который я пытаюсь использовать:Как использовать дженерики в интерфейсе java?

public interface MyInterface<T> 
{ 
    public ArrayList<T> items; 
    //... 
} 

Однако я получаю ошибку о доступе к статической переменной T из не статического контекста и т.д. Как я могу выполнить то, что я пытаюсь сделать? Это, как я предполагаю использовать класс, который реализует этот интерфейс:

MyInterface<SomeObject> foo = new MyInterfaceImpl<>(); 

for (SomeObject bar: foo.items) 
{ 
    bar.someMethod(); 
} 

Возможно ли это указать через интерфейсы?

+0

Изготовление MyInterface продлить Iterable позволит перебирать на него, используя для цикла как вы ее написали. –

+0

Это не проблема, проблема в том, что строка 'public ArrayList items;' дает мне ошибку о доступе к статической переменной T из нестатического контекста –

ответ

0

Вы должны сделать это:

MyInterface<SomeObject> foo = new MyInterfaceImpl<SomeObject>(); 

for (SomeObject bar: foo.items) 
{ 
    bar.someMethod(); 
} 

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

+0

, это именно то, что я разместил. это только фиктивный код. У меня возникли проблемы с кодом в первой части вопроса. –

+0

Это отличается от вашего кода: new MyInterfaceImpl (); – ATrubka

+2

не требуется с Java7 [см. Бриллиант] (http://docs.oracle.com/javase/7/docs/technotes/guides/language/type-inference-generic-instance-creation.html) – oliholz

3

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

От Java Language Specification Sec. 8.1.2

  • Это ошибка времени компиляции для обозначения параметра типа родового класса с в любом месте:
  • декларация статического члена C (§8.3.1.1, §8.4.3.2, §8.5.1), или
  • декларации статического члена какого-либо описания типа вложенных в пределах C, или
  • статический инициализатор С (§ 8.7), или
  • статического инициализатор любого объявления класса вложенного в C.
+0

Как я могу решить это тогда? –

+0

Я не думаю, что это возможно. –

2

Основная проблема является членом данных, который является статическим по умолчанию, когда объявленный в интерфейс.

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

+0

Правильно, я понимаю рассуждения, но как я могу выполнить то, что я хочу? –

+0

Нажмите: Я не уверен, что именно вам нужно. То, что вы не можете сделать наверняка, перебирает статический список и ожидает, что все элементы будут иметь тип SomeObject. Вы уверены, что вам нужен статический глобальный список? или, может быть, вам действительно нужен список на один экземпляр? –

1

В основном интерфейс описывает возможности (ака какого класс может сделать) не реализацию (ака как экземпляр достигает эти возможности).

От this other stackoverflow question

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

То, что вы на самом деле нужны вот абстрактный базового класс

class abstract Base<T> implements MyInterface<T> { 
    //btw it's recommended that you use interfaces as the declaring type not implementations 
    public List<T> items = new ArrayList<T>; 
} 

class MyInterfaceImpl<T> extends Base<T> { 
    //... 
} 

абстрактные базовые классы имеют то преимущество, что они могут включать в себя от 0 до 100% реализации, включая общественность/защиты/частный экземпляр поля.

1

После объяснения Эяль, сделайте так:

public interface MyInterface<T> { 
    Collection<T> getItems(); 
} 

Реализация классов проведет динамический элемент данных:

public class MyImpl<T> implements MyInterface<T> { 
    private Collection<T> items; 
    public Collection<T> getItems() { return items; } 
} 
Смежные вопросы