我正在阅读有关天气的信息,或者在这个SO页面上从构造函数中调用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; } } 举个例子,在完全创建实例之前,如何泄漏此引用? 是否意味着在创建对象之前将其作为参数传递?I was reading about weather or not it's good practice to call a setter from the constructor on this SO page. I'm aware that you shouldn't call non-final methods from your constructor. One of the answers suggests:
Constructors should be cautious about leaking this before the instance is fully initialized.
I don't fully understand what the above quote means. Suppose I have the following class:
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; } } Just as an example, how would I leak the this reference before the instance is fully created? Does it mean passing the object as an argument before it has been created?最满意答案
泄漏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还没有设置它的值。 这是一个漏洞如何在代码中适得其反的例子。
对于第二个问题,调用final或private方法几乎总是在构造函数中有效。 唯一的例外是如果调用依赖于某个值进行初始化的方法,并且在初始化发生之前调用该方法。 但是你的setter不依赖于任何状态,所以情况并非如此,并且它不能在子类中修改(因为它是最终的)所以它没有办法让它行为不端。
Leaking this references can be dangerous because things that look like they should be fully initialized might not be, and that fact can be easily hidden. Here's an example of how it can be problematic using subclassing:
class Foo{ Foo(){ doStuff(); } void doStuff(){} } class Bar extends Foo{ private int i = 1; @Override public void doStuff(){ System.out.println(i); } }You'd think, when instantiating a new instance of Bar, that it would display 1. But instead it displays 0, because the method gets called before Bars constructor runs, and so i hasn't had its value set yet. This is one example of how a leaking this can backfire in code that otherwise looks fine.
For your second question, calling final or private methods is almost always valid in a constructor. The only exception is if you call a method that depends on some value being initialized, and the method is called before that initialization happens. But your setter doesn't depend on any state, so that's not the case, and it can't be modified in a subclass (since it's final) so there's no way for it to misbehave.
麻烦理解“泄漏此参考”(Trouble Understanding “Leaking the this reference”)我正在阅读有关天气的信息,或者在这个SO页面上从构造函数中调用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; } } 举个例子,在完全创建实例之前,如何泄漏此引用? 是否意味着在创建对象之前将其作为参数传递?I was reading about weather or not it's good practice to call a setter from the constructor on this SO page. I'm aware that you shouldn't call non-final methods from your constructor. One of the answers suggests:
Constructors should be cautious about leaking this before the instance is fully initialized.
I don't fully understand what the above quote means. Suppose I have the following class:
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; } } Just as an example, how would I leak the this reference before the instance is fully created? Does it mean passing the object as an argument before it has been created?最满意答案
泄漏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还没有设置它的值。 这是一个漏洞如何在代码中适得其反的例子。
对于第二个问题,调用final或private方法几乎总是在构造函数中有效。 唯一的例外是如果调用依赖于某个值进行初始化的方法,并且在初始化发生之前调用该方法。 但是你的setter不依赖于任何状态,所以情况并非如此,并且它不能在子类中修改(因为它是最终的)所以它没有办法让它行为不端。
Leaking this references can be dangerous because things that look like they should be fully initialized might not be, and that fact can be easily hidden. Here's an example of how it can be problematic using subclassing:
class Foo{ Foo(){ doStuff(); } void doStuff(){} } class Bar extends Foo{ private int i = 1; @Override public void doStuff(){ System.out.println(i); } }You'd think, when instantiating a new instance of Bar, that it would display 1. But instead it displays 0, because the method gets called before Bars constructor runs, and so i hasn't had its value set yet. This is one example of how a leaking this can backfire in code that otherwise looks fine.
For your second question, calling final or private methods is almost always valid in a constructor. The only exception is if you call a method that depends on some value being initialized, and the method is called before that initialization happens. But your setter doesn't depend on any state, so that's not the case, and it can't be modified in a subclass (since it's final) so there's no way for it to misbehave.
发布评论