Java最佳实践 - 返回对象与通用

时间:2013-11-08 15:44:31

标签: java object generics junit

我第一次在学校项目中使用泛型,我遇到了一个关于是否在我的方法中返回对象或我声明的泛型元素的哲学困境。

我的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());

另一方面,当我返回一个对象时,自动装箱不会强迫我施放原始值。

以下是对我所面临问题的更有说服力的描述:

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类型不明确

---------结束编辑--------------

问题

  1. 任何人都可以告诉我为什么我应该或不应该返回一个对象而不是我正在使用的通用元素?两者似乎都有好处和缺点......什么是最佳做法?

  2. 我隐约知道返回一个Object可能会导致一些投射问题,但我还没有碰到它们......有没有人有一个具体的例子说明这可能是危险的?

    < / LI>
  3. 在JDK中,我注意到许多Collections方法默认返回Object。这是因为Generics是在Java的更高版本中引入的还是Sun Systems的有意识决定?

1 个答案:

答案 0 :(得分:8)

  

任何人都可以告诉我为什么我应该或不应该返回一个对象,而不是我正在使用的通用元素?两者似乎都有好处和缺点......什么是最佳做法?

这取决于。在这种情况下,您需要泛型类型 - 否则为类定义泛型类型有什么意义?

  

我隐约知道返回一个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,字符串和图标,例如用于渲染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);

这应该没有问题,对吧?