2009-05-25 3 views

ответ

10

кажется, поражение цели generics, но здесь идет:

Stack<Object>s = new Stack<Object>(); 
s.add("hello"); 
s.add(1);   // int is autoboxed to Integer 

Улов будет то, что при извлечении Object S из Stack, он собирается предпринять некоторые усилия, чтобы выяснить, какой тип каждый элемент - это потребует использования instanceof и преобразования типов:

while (!s.isEmpty()) { 
    Object e = s.pop(); 

    if (e instanceof String) 
    System.out.println("String: " + (String)e); 
    else if (e instanceof Integer) 
    System.out.println("Integer: " + (Integer)e); 
    else 
    System.out.println("Other type: " + e); 
} 

и теперь у нас есть что-то похожее на хрупкий код предварительной Java 5 дней до дженерик были добавлен к языку.

+1

Опасность заключается в том, когда вы извлекаете элементы позже, вам нужно написать проверки типов объектов. – Joset

+0

Абсолютно - я только что закончил добавление этой части в качестве редактирования. – coobird

6

Как правило, вы захотите решить это, используя наследование. Возможно, с помощью интерфейса маркера:

interface MyMarker 
{ 
} 

class Foo implements MyMarker 
{ 
} 

class Bar implements MyMarker 
{ 
} 

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

Вы можете поместить Foo и Bar в одном стеке:

Stack<MyMarker> s = new Stack<MyMarker>(); 
s.add(new Foo()); 
s.add(new Bar()); 

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

+2

Это определенно лучший способ - всякий раз, когда есть лестница if-elseif из «instanceof», решение обычно является наследованием. – coobird

0

Общий аргумент стека должен быть общим супер-типом всех типов времени выполнения элементов. Для полностью гетерогенных коллекций Object является общим супертипом всех ссылочных типов. Итак:

Queue<Object> stack = Collections.asLifoQueue(new ArrayDeque<Object>()); 
stack.add("red"); 
stack.add(Color.GREEN); 
stack.add(stack); 

Очевидно, что вы, когда вы приходите к попам этих элементов из стека вам нужно будет сделать instanceof проверку на путь к соответствующему коду (и, вероятно, отливать).

Возможно, лучше ввести слой косвенности. Вместо того, чтобы напрямую помещать объекты в очередь, оберните их значимым объектом. Проверки instanceof могут быть заменены вызовами (виртуальными) методами, которые выполняют требуемые операции. Вот как должен выглядеть полиморфизм.

Смежные вопросы