Java=返回对象列表/数组与结果对象(与方法参数相同)
这似乎是一个奇怪的问题:我正在努力确定在非常精细的级别上处理“类型化对象”是否是一种良好的实践和“有效的”Java=返回对象列表/数组与结果对象(与方法参数相同),java,oop,Java,Oop,这似乎是一个奇怪的问题:我正在努力确定在非常精细的级别上处理“类型化对象”是否是一种良好的实践和“有效的” public Object[] doSomething() { Object[] resultList = new Object[] {new Foo(), new Bar()}; return resultList; } 对 public Result doSomething() { Result result = new Result(); resul
public Object[] doSomething() {
Object[] resultList = new Object[] {new Foo(), new Bar()};
return resultList;
}
对
public Result doSomething() {
Result result = new Result();
result.foo = new Foo();
result.bar = new Bar();
return result;
}
public class Result{
Foo foo;
Bar bar;
}
我的问题具体如下:
public doSomething(Query query )
对
public doSomething(Foo foo, Bar bar, Aaaa, a, Bbbbb)
public doSomething(Foo foo, Bar bar)
谢谢
马库斯
3.)在“良好的设计实践”方面。您是否认为版本1是绝对不可能的,或者您更愿意认为它实际上并不重要……或者您是否会建议永不返回“对象数组”((在面向对象编程语言中/关于封装…))
第1版是绝对禁止的。它几乎完全没有类型。调用者必须知道实际的类型以及它们在数组中的位置,并进行适当的强制转换。您将丢失任何有用的编译时类型检查,并且代码本身明显不太清晰
我永远不会返回
对象[]
,除非它包含的值是用新对象()
构造的。我不相信定义结果
类和返回比构造对象[]
在运行时消耗更多的资源。(当然,存储和加载类定义的成本微乎其微。)您是否有其他指示的数据
返回非类型化对象数组是一种糟糕的做法,原因有很多,其中包括:
public doSomething(Query query)
对
public doSomething(Foo foo, Bar bar, Aaaa, a, Bbbbb)
public doSomething(Foo foo, Bar bar)
这一点不那么明确。如果将
Foo
和Bar
打包成Query
对象在问题域中是有意义的,那么我肯定会这么做。如果只是为了最小化参数数量而打包(也就是说,在您的问题域中没有“查询对象”概念),那么我可能不会这么做。如果这是一个运行时性能的问题,那么答案是(一如既往地)评测。我必须做一个实验才能真正知道,但我猜对象数组不会明显更快。它甚至可能更慢。毕竟,无论哪种情况,都必须创建一个对象:数组对象或结果对象。对于结果对象,您必须在第一次使用它时从磁盘读取类定义,并且类定义必须在内存中浮动,因此会有一些额外的成本。但是,对于array对象,您必须在拉出数据时进行强制转换,JVM必须对数组进行边界检查(如果调用方尝试检索resultList[12]?),这也需要额外的工作。我的猜测是,如果只执行一次或两次,数组将更快(因为类加载时间),但如果执行多次,专用对象将更快(因为强制转换和数组访问时间)。但我承认我只是在猜测
在任何情况下,即使阵列确实有一点性能优势,代码可读性和可维护性的损失几乎肯定是不值得的
最糟糕的情况是,如果数组中返回的值属于同一类,但语义不同。假设你这样做了:
public Object[] getCustomerData(int customerid)
{
String customerName=... however you get it ...
BigDecimal currentDue=...
BigDecimal pastDue=...
return new Object[] {customerName, pastDue, currentDue};
}
... meanwhile, back at the ranch ...
Object[] customerData=getCustomerData(customerid);
BigDecimal pastDue=(BigDecimal)customerData[2];
if (pastDue>0)
sendNastyCollectionLetter();
你看到错误了吗?当条目#2应该是#1时,我将其检索为pastDue。你可以很容易地想象,如果一个程序员在一个不考虑的时刻,从一开始而不是从零开始计算字段,就会发生这种情况。或者如果他算错了,说“14”,而实际上是“15”。由于两者都有相同的数据类型,因此可以很好地编译和运行。但我们将向未到期的客户发送不适当的催款信。这对客户关系非常不利
好吧,也许这是一个糟糕的例子——我只是把它从我的头顶上扯下来——因为我们很可能在测试中发现它。但是,如果我们切换的值很少使用,以至于没有人想到为它们包含一个测试场景,该怎么办呢。或者它们的影响很微妙,因此错误可能会在测试中漏掉。就这一点而言,如果您匆忙完成一项更改,或者如果测试人员出错,等等,那么您可能在测试中无法捕捉到这一点。3)。对的案例1是不可能的。当涉及到开发代码时,最重要的事情是使代码可维护,而案例1很难维护。对于代码可读性(如果不是其他的话)。选项2)会稍微快一点,因为在使用结果时消除了强制转换,而且根据JVM实现,每次调用可能会节省4-8字节(因为结果将小于对象[2])+1。事实上,在大多数当前的JVM实现中,结果的开销可能比对象[2]要小,因为数组除了普通的对象头之外还包含一个额外的数组长度字段。我唯一返回对象[]的时候是如果返回的对象确实是一组不同类型的对象,数组中的位置没有语义意义。也就是说,调用者不认为#1是userid,而#2是passw