简体   繁体   English

在 Java 中将方法调用链接到构造函数是一个好习惯吗?

[英]Is chaining method calls to constructors a good practice in Java?

I have always thought that I have to initialize a class, before I can call it's non-static method, however, I came across a solution which had a method like this in it:我一直认为我必须初始化一个类,然后才能调用它的非静态方法,但是,我遇到了一个解决方案,其中包含这样的方法:

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

So I may be new in development, but is it a good practice?所以我可能是开发新手,但这是一个好的做法吗? Is this a better way to call a method than the "classic" (see below) way?与“经典”(见下文)方式相比,这是一种更好的调用方法的方式吗?

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

Do they have any performance difference?它们有什么性能差异吗? Does the first way has a "special name"?第一种方式有“特殊名称”吗?

No significant difference无显着差异

As the comments explained, both approaches are semantically the same;正如评论所解释的,这两种方法在语义上是相同的; both ways achieve the exact same result and the choice is really just a stylistic difference.两种方式都能达到完全相同的结果,选择实际上只是风格上的差异。

The second approach assigns the new object to a reference variable.第二种方法将新对象分配给引用变量。 The first approach skips the use of a reference variable.第一种方法跳过了引用变量的使用。 But in both cases the class was used as a definition for instantiating an object, and then the toString method was called on that object.但在这两种情况下,类都被用作实例化对象的定义,然后在该对象上调用toString方法。

Semantically, first (chained/fluent) syntax usually informs you that the created object will be used only for a single chain of operations, and discarded afterwards.在语义上,first (chained/fluent) 语法通常会通知您创建的对象将仅用于单个操作链,然后被丢弃。 Since there's no explicit reference exported, it also signals that the scope of life of the object is limited to that very statement.由于没有显式引用导出,它还表明对象的生命范围仅限于该语句。 The second (explicit) one hints that the object is/was/will be used for additional operations, be it another method calls, setting a field to it, returning it, or even just debugging.第二个(显式)暗示该对象是/曾经/将用于其他操作,无论是另一个方法调用,设置一个字段,返回它,甚至只是调试。 Still, the general notion of using (or not) temporary helper variables is just a stylistic one .尽管如此, 使用(或不使用)临时辅助变量的一般概念只是一种风格

Keep in mind that the variable is not the object.请记住,变量不是对象。 For example, the line Dog hershey = new Dog( "Australian Shepard" , "red", "Hershey" );例如, Dog hershey = new Dog( "Australian Shepard" , "red", "Hershey" ); uses two chunks of memory.使用两块内存。 In one chunk is the new object, holding the state data for the breed and color and name.一个块是新对象,保存品种、颜色和名称的状态数据。 In the other separate chunk is the reference variable hershey holding a pointer to the memory location of the memory chunk of the Dog object.在另一个单独的块中是引用变量hershey持有一个指向 Dog 对象的内存块的内存位置的指针。 The reference variable lets us later refer to the object.引用变量让我们稍后引用对象。

Java syntax makes this jump from reference variable to object so seamlessly that we usually think of hershey as the Dog object “Hershey”, but in fact they are separate and distinct. Java 语法使这种从引用变量到对象的跳转如此无缝,以至于我们通常将hershey视为Dog对象“Hershey”,但实际上它们是独立且不同的。

As for performance, any difference would be insignificant.至于性能,任何差异都无关紧要。 Indeed, the compiler or JVM may well collapse the second approach's two lines into the first approach's single line.实际上,编译器或 JVM 很可能会将第二种方法的两行合并为第一种方法的单行。 I don't know for sure, and I don't really care.我不确定,我也不在乎。 Neither should you.你也不应该。 Our job is to write clear readable code.我们的工作是编写清晰易读的代码。 The job of the compiler and JVM is to run that code reliably, efficiently, and fast.编译器和 JVM 的工作是可靠、高效和快速地运行该代码。 Attempting micro-optimizations has been shown many times to be futile (or even counter-productive) as the JVM implementations are extremely sophisticated pieces of software engineering, highly-tuned for making such optimizations.尝试微优化已多次被证明是徒劳的(甚至适得其反),因为 JVM 实现是极其复杂的软件工程部分,经过高度调整以进行此类优化。 You can best assist the compilers and JVMs by writing simple straight-forward code without “cleverness”.您可以通过编写简单直接的代码而不是“聪明”来最好地帮助编译器和 JVM。

Note that the second approach can make debugging easier, because your debugger can inspect the instantiated object by accessing the object via the reference variable, and because you can set a line breakpoint on that particular constructor call explicitly.请注意,第二种方法可以使调试更容易,因为您的调试器可以通过引用变量访问对象来检查实例化的对象,并且因为您可以在该特定构造函数调用上显式设置行断点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM