麻烦理解“泄漏此参考”

时间:2016-09-23 16:57:07

标签: java constructor setter

我正在阅读有关天气的信息,或者不是从这个SO page的构造函数中调用一个setter是一种好习惯。我知道你不应该从构造函数中调用非final方法。其中一个答案表明:

  

构造函数应该在实例之前谨慎泄漏它   完全初始化。

我不完全明白上述报价的含义。假设我有以下课程:

public final class Employee
{
    private String empID;
    private String empFirstName;
    private String empLastName;

    public Employee(String ID, String FirstName, String LastName)
    {
        //Call to other setters left out. 
        this.setEmployeeLastName(LastName);

    }

    //empID, empFirstName setter left out.
    public void setEmployeeLastName(String lastname)
    {
        this.empLastName = lastname;
    }
}
  1. 仅作为示例,在完全创建实例之前,如何泄漏此引用?是否意味着在创建之前将对象作为参数传递?

1 个答案:

答案 0 :(得分:1)

泄漏this引用可能很危险,因为看起来应该完全初始化的内容可能不是,并且可以很容易地隐藏这个事实。以下是使用子类化可能会出现问题的示例:

class Foo{
    Foo(){
        doStuff();
    }
    void doStuff(){}
}

class Bar extends Foo{
    private int i = 1;
    @Override
    public void doStuff(){
        System.out.println(i);
    }
}

您认为,在实例化Bar的新实例时,它会显示1。但是它显示0,因为该方法在Bar构造函数运行之前被调用,因此i尚未设置其值。这是泄漏this如何在代码中适得其反的一个示例,否则看起来不错。

对于第二个问题,调用finalprivate方法几乎总是在构造函数中有效。唯一的例外是如果调用依赖于某个值进行初始化的方法,并且在初始化发生之前调用该方法。但是你的setter不依赖于任何状态,所以情况并非如此,并且它不能在子类中修改(因为它是最终的)所以它没有办法让它行为不端。