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

Dan*_*anK 4 java generics junit object

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

我的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);
}
Run Code Online (Sandbox Code Playgroud)

(作为一个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());
Run Code Online (Sandbox Code Playgroud)

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

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

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

- - - - - - 编辑 - - - - - - - -

这是我返回泛型类型并使用自动装箱的Integer对象填充我的列表而没有上面的强制转换时收到的实际错误:方法assertEquals(String,Object,Object)对于DansPriorityQueueTest类型是不明确的

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

问题

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

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

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

Mar*_*sto 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
Run Code Online (Sandbox Code Playgroud)

在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);
Run Code Online (Sandbox Code Playgroud)

这应该没有问题,对吧?