2014-02-13 2 views
1

Рассмотрим этот гипотетический класс (который я нашел в Интернете видео):дженерики в конструкторах в Java?

public class Contrived<T extends Number> extends ArrayList<T> { 
     List <? extends T> values; 
     ...... 
    } 

Здесь переменные типа, которые могут принимать Contrived является Number или какой подтип Number. Но сам класс наследуется от ArrayList, поэтому любой тип, который получает класс, определит тип ArrayList.

Теперь есть поле под названием values, которое составляет List<? extends T values>. так что это значит? Содержит ли list все, что распространяется на T (что, в свою очередь, распространяется Number).

от PECS (producer extends, consumer super) правило, могу ли я использовать это List для чтения элементов, но не добавить в list.

Как будет выглядеть constructor, если мне нужно пройти list of doubles or some type T?

+1

Я не думаю, что я полностью понял идею класса «Пропитанный». Что он должен делать? Он расширяет 'ArrayList' и имеет список' values' как ссылочную переменную. Класс, таким образом, в основном содержит два списка, каково намерение класса? От этого зависит полезный конструктор (например, «Что должен делать конструктор?»). Можете ли вы ссылаться на источник? – dst

+0

@ dst: это гипотетический класс. ничего важного он не делает как таковой. но мне интересно, как будет выглядеть конструктор для него, и какие операции можно выполнить с помощью данного поля 'list'? –

+0

'public Прозревший (Список ))? –

ответ

2

У вас может быть конструктор, который принимает List<T> или List<? extends T>. Продолжая изловчиться классы:

class B extends Number{ 
    public double doubleValue() { return 0; } 
    public float floatValue() { return 0; } 
    public long longValue() { return 0; } 
    public int intValue() { return 0; } 
} 
class C extends B{} 

добавить надуманный, правовой конструктор к Contrived класса, принимая List<? extends T>:

public Contrived(List<? extends T> values) 
{ 
    this.values = values; 
} 

Это позволяет мне написать метод main такие как:

public static void main(String[] args) 
{ 
    List<C> bList = Arrays.asList(new C(), new C(), new C()); 
    Contrived<B> ci = new Contrived<B>(bList); 
} 

Я могу передать List<C> в конструктор для Contrived<B>.

Другой дизайн для ухитренный конструктора, который является законным для Contrived может быть, принимая List<T>:

public Contrived(List<T> values) 
{ 
    this.values = values; 
} 

Такой конструктор не позволяет List<C> для Contrived<B>, потому что теперь типы должны совпадать, так как в следующих двух примерах: Contrived

public static void main(String[] args) 
{ 
    List<C> cList = Arrays.asList(new C(), new C(), new C()); 
    Contrived<C> ci = new Contrived<C>(cList); // must match now 
} 

И

public static void main(String[] args) 
{ 
    List<B> bList = Arrays.asList(new B(), new B(), new B()); 
    Contrived<B> ci = new Contrived<B>(bList); // must match now 
} 
+1

Пока мы говорим надуманно, вы также можете присвоить значения 'this' to' '. – Radiodef

+0

@ Radiodef Подтвержденный, ваш надуманный пример, 'this.values ​​= this;', является законным внутри любого из моих надуманных конструкторов 'Contrived'. – rgettman

+0

могут иметь оба конструктора в случае перегрузки, но это не имеет смысла в этом случае, я полагаю; так как первая - это расслабленная версия последнего, ограниченная ...? –