Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java=返回对象列表/数组与结果对象(与方法参数相同)_Java_Oop - Fatal编程技术网

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;
}
我的问题具体如下:

  • 就CPU周期而言(作为一个相对数字),第二种方法消耗了多少资源。(大约100%以上)

  • 在内存消耗方面也有同样的问题

  • 注意(这两个问题需要更多地理解,不是关于过早优化的问题)

  • 在“良好设计实践”方面。您是否认为版本1是绝对不可能的,或者您更愿意认为它实际上并不重要……或者您会建议永远不要返回“对象数组”((在面向对象编程语言中))
  • 这是一个问题,我一直在想,我是应该为所有东西创建专用对象(用于传递值),还是应该使用通用对象(和公共方法参数…)

    这个问题也适用于

    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