在java中的方法调用接受实践中传递'this'

max*_*130 92 java

在方法调用中传递当前对象是好/坏/可接受的做法.如:

public class Bar{
    public Bar(){}

    public void foo(Baz baz){
        //  modify some values of baz
    }
}

public class Baz{
    //constructor omitted

    public void method(){
        Bar bar = new Bar();
        bar.foo(this);
    }
}
Run Code Online (Sandbox Code Playgroud)

具体来说,线路是否bar.foo(this)可以接受?

mor*_*ano 164

这没什么不对.什么不是一个好的做法是在内部构造函数中执行相同的操作,因为您将提供对尚未完全初始化的对象的引用.

这里有一个类似的帖子:Java在构造函数泄漏它,它们解释了为什么后者是一个不好的做法.

  • +1:很好地指出了在构造函数中引用'this'的危险性. (18认同)
  • @LieRyan`Warge`完全从属于'Car`,IMO根本不应该知道'Car`. (6认同)
  • 在构造函数中使用`this`的唯一坏处是,如果将`this`传递给一个方法或上下文,从该方法或上下文中将尚未完全构造的对象引用发布到不受信任或未知的客户端(或假定的客户端代码)它有一个完全构造的对象的视图).在我看来,将`this`从构造函数传递给执行常见初始化的package-private方法不仅可以接受,而且是可取的. (3认同)

Den*_*ret 152

没有理由不使用它,this是当前的实例,它是完全合法的使用.事实上,通常没有简洁的方法来省略它.

所以使用它.

因为没有例子很难说服它是可以接受的(对这样一个问题的否定答案总是更易于论证),我只打开了一个最常见的java.lang类,String一个,当然我发现了这种用法的实例,例如

1084        // Argument is a String
1085        if (cs.equals(this))
1086            return true;
Run Code Online (Sandbox Code Playgroud)

寻找(this在大"接受"的项目,你不会不发现它.

  • -1答案是因为您在问题中找到了可以评论的其他小细节?真的吗? (34认同)
  • -1因为没有提到双向类关系比单向关系更复杂的事实.确保软件尽可能清晰至关重要.在上面的具体示例中,[Move Method](http://sourcemaking.com/refactoring/move-method)foo对Baz类更为明智,以避免在两个类之间进行双向引用并带来行为和数据在一起. (15认同)
  • @dystroy是的我不同意你的开场白:"没有理由不使用它". (13认同)
  • 完美答案. (6认同)
  • 实际上,在实际代码中(与OP的简化示例相反),传递`this`并不意味着您添加双向链接,因为例如继承和接口. (4认同)
  • @dystroy No.我给-1,因为如果可能的话避免双向链接很重要.因此,我完全不同意答案.这就是downvote的用途. (2认同)
  • @JW.你更喜欢`this.fooBy(new Bar());`?这完全是个人风格.我认为没有理由你的-1,或者......(在某些情况下它更难读,因为动作(功能)名称必须颠倒) (2认同)

Ste*_* T. 42

是的,但你应该小心两件事

  1. 在尚未构造对象时传递对象(即在其构造函数中)
  2. 将此传递给长寿命对象,这将使引用保持活动状态,并防止对象被垃圾回收.


Bat*_*eba 13

这是完全正常的,完全可以接受的.


Jun*_*san 5

这代表当前的对象.你正在做的是sytatically正确,但如果你在同一个类中调用该方法,我认为不需要这样做.

  • 在示例代码中,Baz.method()是一个实例方法,它使用Baz实例作为参数调用Bar.foo().因此OP不会在同一个类中调用方法. (2认同)

JW.*_*JW. 5

如果有不太复杂的替代方案来实现相同的行为,那么在方法调用中传递当前对象是不好的做法。

\n\n

this根据定义,一旦从一个对象传递到另一个对象,就会创建双向关联。

\n\n

引用 Martin Fowler 的《重构》:

\n\n
\n

将双向关联更改为单向 (200)

\n\n

双向关联很有用,但它们是有代价的。代价是维护双向链接和确保正确创建和删除对象所增加的复杂性。双向关联对于许多程序员来说并不自然,因此它们通常是错误的来源

\n\n

...

\n\n

您应该在需要时使用双向关联,但在不需要时则不使用\xe2\x80\x99t。一旦您发现双向关联不再发挥其作用,请删除不必要的末端。

\n
\n\n

this因此,从理论上讲,当我们发现需要通过并努力想其他方法来解决手头的问题时,我们应该听到警钟。当然,有时候,在最后的手段下,这样做是有意义的。

\n\n

此外,在长期重构代码以实现整体改进的过程中,通常有必要暂时破坏您的设计,做“不好的做法”。(后退一步,前进两步)。

\n\n

在实践中,我发现通过避免像瘟疫一样的双向链接,我的代码得到了巨大的改进。

\n

  • @JW:这个答案中给出的推理是无关紧要的。对于任何 X 值,如果有其他更简单的方法,那么执行 X 总是一个坏主意。 (2认同)