【问题标题】:Is chaining method calls to constructors a good practice in Java?将方法调用链接到构造函数是 Java 中的一种好习惯吗?
【发布时间】:2016-05-13 15:32:03
【问题描述】:

我一直认为我必须先初始化一个类,然后才能将其称为非静态方法,但是,我遇到了一个解决方案,其中包含这样的方法:

public String someStringMethod(){
    return new MyClass().toString();
}

所以我可能是开发新手,但这是一个好习惯吗?与“经典”(见下文)方式相比,这是一种更好的方法调用方式吗?

public String classicStringMethod(){
    MyClass cl = new MyClass();
    return cl.toString();
}

它们有什么性能差异吗?第一种方式有“特殊名称”吗?

【问题讨论】:

  • 他们有什么性能差异吗?第一种方式有“特殊名称”吗? 没有。 它们是等价的。除了保存对局部变量的引用(或不保存)之外,它没有我知道的特殊名称。
  • 两种方式都达到了完全相同的结果。这实际上只是风格上的差异。我更喜欢第二种风格。感觉对追我的人或看着它的可怜的人来说更清楚一点,而他们在深夜试图调试时扯下头发。通常,编译器/优化器会将其解析为相同的字节码。
  • 谢谢你的回答,现在很清楚了。
  • 糟糕,我敢肯定,在上面的评论中看到“fluid”这个词的地方,打“fluent”的意思是混乱。
  • 您问题的标题提出的问题与正文略有不同。要回答标题中提出的问题,为什么丢弃对 Java 中有效的新实例的引用?简短的回答是:Garbage Collection。创建一个对象,用它做某事(甚至什么都不做),然后再也不引用它是完全有效的。 VM 会清理它。

标签: java class methods


【解决方案1】:

无显着差异

正如 cmets 所解释的,这两种方法在语义上是相同的;两种方式都达到了完全相同的结果,而选择实际上只是风格上的差异。

第二种方法将新对象分配给引用变量。第一种方法跳过了引用变量的使用。但在这两种情况下,该类都被用作实例化对象的定义,然后对该对象调用 toString 方法。

从语义上讲,第一个(链式/流利的)语法通常会通知您创建的对象将仅用于单个操作链,然后被丢弃。由于没有导出明确的引用,这也表明对象的生命范围仅限于该语句。第二个(显式)暗示该对象是/曾经/将用于其他操作,无论是另一个方法调用,为其设置字段,返回它,甚至只是调试。不过,the general notion of using (or not) temporary helper variables is just a stylistic one

请记住,变量不是对象。例如,Dog hershey = new Dog( "Australian Shepard" , "red", "Hershey" ); 行使用 两个 内存块。一大块是新对象,保存品种、颜色和名称的状态数据。在另一个 separate 块中是引用变量hershey,它持有指向 Dog 对象的内存块的内存位置的指针。引用变量让我们稍后可以引用该对象。

Java 语法使得这种从引用变量到对象的跳转如此无缝,以至于我们通常将hershey as 视为Dog 对象“Hershey”,但实际上它们是独立且不同的。

至于性能,任何差异都是微不足道的。事实上,编译器或 JVM 很可能将第二种方法的两行代码折叠成第一种方法的一行代码。我不确定,我也不在乎。你也不应该。我们的工作是编写清晰易读的代码。编译器和 JVM 的工作是可靠、高效、快速地运行代码。多次尝试微优化已被证明是徒劳的(甚至适得其反),因为 JVM 实现是非常复杂的软件工程部分,为进行此类优化而进行了高度调整。您可以通过编写简单直接的代码而不需要“聪明”来最好地帮助编译器和 JVM。

请注意,第二种方法可以使调试更容易,因为您的调试器可以通过引用变量访问对象来检查实例化对象,并且您可以在该特定构造函数调用上显式设置行断点。

【讨论】:

  • @vaxquis 我同意你的看法。但实际上,调试需求胜出。似乎每次我跳过辅助变量时,我都会后悔,因为需要在调试器中检查它,所以不得不返回编辑源代码以添加额外的行。我说的是编写自己的糟糕代码。我已经习惯了这种从重写到启用调试的方式,以至于我已经将引用将被重用(如你所说)的暗示从我的脑海中剔除。对于调试良好的代码,尤其是针对公共开源等更广泛的程序员群体时,您的建议是明智的。
  • 感谢您的详细解答。我想我还处于一个新手时代,我正在努力应用我在学校学到的一切,就像我学到的一样。正如您所提到的,我想我将继续使用辅助变量方法进行调试。
  • @vaxquis 我们同意。这是一个很好的交流记录。
  • @BasilBourque 在那种情况下,我冒昧地改写一下你的答案;我还引用了您提到的 muglio 的引用,因为评论引用极容易出现评论腐烂(例如用户重命名等),并提到了第二种解决方案如何允许简单的 c-tor 行断点。当然,如果您不同意,请随时恢复编辑。
猜你喜欢
  • 1970-01-01
  • 2019-02-01
  • 2021-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-11
  • 1970-01-01
  • 2016-12-11
相关资源
最近更新 更多