2013-11-08 4 views
4

Я впервые использую Generics для школьного проекта, и я столкнулся с философской дилеммой относительно того, возвращать ли объекты или мой объявленный общий элемент в моих методах.Практические примеры Java - возврат объекта к общему

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

Вот пример того, что я имею в виду:

public class DansPriorityQueue<E extends Comparable> 
{ 
    private ArrayList<E> tree; 

//Here's a method that returns an object 
public Object peek() { 
    return tree.get(0); 
} 

//Here's a method that returns the generic type 
public E peek() { 
    return tree.get(0); 
} 

(В качестве FYI .. Я должен реализовать этот JDK класс сам, но я, к счастью, не требуется реализовать те же интерфейсы, что реальный PriorityQueue делает это у меня есть выбор, ли я хочу использовать объект или общий)

Мой выпуск

Это заставляет меня чувствовать себя аль ittle грязный, но я испытываю просто вернуть объект, а не мой E общего элемента на этих методов, потому что, когда я вернусь Е, JUnit силы, чтобы я бросил мои целые значения:

DansPriorityQueue<Integer> dpq = new DansPriorityQueue<Integer>(); 
dpq.add(1); 
assertEquals("Expected different value", (Integer) 1, dpq.peek()); 

Когда я вернусь объект на с другой стороны, авто-бокс не заставляет меня отличать мое примитивное значение.

Вот более красноречив описание проблемы я столкнулась:

http://www.aschroder.com/2009/10/php-1-java-0-the-method-assertequalsobject-object-is-ambiguous-for-the-type/

------------ EDIT --------- -------

Вот реальная ошибка, которую я получаю, когда возвращаю родовой тип и заполняю свой список автобоксированным объектом Integer без приведения выше: Метод assertEquals (String, Object, Object) неоднозначен для типа DansPriorityQueueTest

--------- END EDIT --------------

Вопросы

  1. Может кто-нибудь сказать мне, почему я должен или не должен возвращать объект, а не общий элемент, с которым я работаю? У обоих, кажется, есть проблемы и недостатки ... Какая практика?

  2. Я смутно знаю, что возвращение объекта может вызвать некоторые проблемы с кастомизацией позже, но я еще не столкнулся с ними ... есть ли у кого-нибудь конкретный пример того, как это может быть опасно?

  3. В JDK я заметил, что многие из методов Collections возвращают Object по умолчанию. Это потому, что Generics была представлена ​​в более поздней версии Java или это было сознательное решение Sun Systems?

+0

Можете ли вы не просто параметризовать общий с помощью Integer, и все это работает на вас с помощью магии автобоксинга? – InfernalRapture

+2

Что означает 'dpq.size()' как возвращаемый тип? Я немного смущен, потому что ваш пример использует вызов, который, кажется, не использует 'peek()' вообще, поэтому не уверен, что я понимаю релевантность. 'size()' не является методом, который был бы общим для типа элемента коллекции. –

+0

Извините, что я отредактировал его с помощью метода peek выше ... Я схватил неправильный тест. – DanK

ответ

8

Может кто-нибудь сказать мне, почему я должен или не должен возвращать объект, в отличие от общего элемента я работаю? У обоих, кажется, есть проблемы и недостатки ... Какая практика?

Это зависит. В таком случае вы бы хотели получить общий тип - иначе в чем смысл определения родового типа для класса?

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

Уверенный!

DansPriorityQueue<String> queue = new DansPriorityQueue<String>(); 
//add items 
Float f = (Float)queue.getObject(); //uh-oh! this compiles but will fail 
Float f = queue.getObject(); //generic type, fails during compile 

В JDK, я заметил, что многие из методов Collections возврата объекта по умолчанию. Это потому, что Generics была представлена ​​в более поздней версии Java или это было сознательное решение Sun Systems?

Это из-за обратной совместимости в основном, или в случаях, когда вы действительно будете использовать коллекцию содержать разнородные значения (путаницей скажем, JLabels, струнных и иконки, например, для рендеринга JTable, например).

assertEquals («Ожидаемый разный размер», (целочисленный) 2, dpq.size());

Я не думаю, что это должно быть проблемой. dpq.size() должен просто возвращать int независимо от того, что хранится в очереди приоритетов. Это не будет общей ценностью.

Вы можете создать что-то вроде

DansPriorityQueue<Double> queue = new DansPriorityQueue<Double>(); 
for(double d = 0; d < 10; d+=1.0) 
    queue.add(d); 

и что не должно вызывать никаких проблем, не так ли?

+0

Спасибо Markus .. это очень полезно. Я перечислил неправильный метод тестирования до этого. заглянуть в автоматическое ядро ​​Integer, и я возвращаю явный общий тип, я получаю fo llowing error, если я не применил его: метод assertEquals (String, Object, Object) неоднозначен для типа DansPriorityQueueTest – DanK

+0

Конечно, это неоднозначно, если у вас есть оба типа возвращаемых типов. Однако, если вы удалите общедоступный объект peek() -method, не останется никакой двусмысленности. –

+0

:-) У меня есть два метода заглянуть только для иллюстрации. В моем проекте есть только один метод peek. Неоднозначность заключается в том, что я перечисляю значение int в своем тесте, но мой класс возвращает объект Integer. По какой-то причине он не может смириться с этими двумя. См. Ссылку выше для более подробной информации. – DanK

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