我第一次在学校项目中使用泛型,并且遇到了关于在方法中返回对象还是声明的泛型元素的哲学难题。
我的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相同的接口,因此我可以选择要使用Object还是泛型)
我的问题
这让我感到有些肮脏,但是我很想在这些方法上返回一个Object而不是我的E泛型元素,因为当我返回E时,JUnit迫使我强制转换我的整数值:
DansPriorityQueue<Integer> dpq = new DansPriorityQueue<Integer>();
dpq.add(1);
assertEquals("Expected different value", (Integer) 1, dpq.peek());
另一方面,当我返回一个对象时,自动装箱不会强制我转换原始值。
这是我所面临问题的更雄辩的描述:
- - - - - - 编辑 - - - - - - - -
这是当我返回泛型类型并用自动装箱的Integer对象填充列表而不进行上面的强制转换时收到的实际错误:对于类型DansPriorityQueueTest,assertEquals(String,Object,Object)方法不明确
---------结束编辑------------------
问题
谁能告诉我为什么我应该或者不应该返回一个与我正在使用的通用元素相对的对象?两者似乎都有优点和缺点...最佳做法是什么?
我隐约知道,返回一个Object可能会在以后引起一些转换问题,但是我还没有遇到它们……有没有人有具体的例子说明这可能是危险的?
在JDK中,我注意到许多Collections方法默认情况下都返回Object。这是因为Generics是在Java的更高版本中引入的,还是Sun Systems的一个有意识的决定?
谁能告诉我为什么我应该或者不应该返回一个与我正在使用的通用元素相对的对象?两者似乎都有优点和缺点...最佳做法是什么?
这取决于。在这种情况下,您需要泛型-否则为类定义泛型有什么意义?
我隐约知道,返回一个Object可能会在以后引起一些转换问题,但是我还没有遇到它们……有没有人有具体的例子说明这可能是危险的?
当然!
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方法默认情况下都返回Object。这是因为Generics是在Java的更高版本中引入的,还是Sun Systems的一个有意识的决定?
这主要是由于向后兼容性,或者是在您真正将使用集合包含完全不同的值的情况下(例如,JLabels,Strings和Icons的混搭,例如用于呈现JTable)。
assertEquals(“ Expected different size”,(Integer)2,dpq.size());
我不认为这应该是一个问题。dpq.size()应该只返回一个int值,而不管优先级队列中存储的内容是什么。这将不是一个通用值。
您可以创建类似
DansPriorityQueue<Double> queue = new DansPriorityQueue<Double>();
for(double d = 0; d < 10; d+=1.0)
queue.add(d);
那应该不会有问题吧?
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句