在java构造函数中传递“this”

查看以下代码:

public class ClassA { private boolean ClassAattr = false; public ClassA() { ClassAHandler handler = new ClassAHandler(this); } } public class ClassAHandler extends GeneralHandler { ClassA ca = null; public ClassAHandler(ClassA classa) { this.ca = classa; } } 

我需要在一些ClassAHandler方法和其他属性中访问ClassAattr 。 有没有办法在没有在处理程序构造函数中传递原始类的情况下这样做。 我真的不喜欢这个解决方案“看起来”。

将其传递给构造函数内部的另一个方法/对象可能相当危险。 当从构造函数内部查看对象时,许多保证对象通常不会成立。

例如,如果您的类具有final (非static )字段,那么您通常可以依赖于它被设置为值并且永远不会更改。

当您查看的对象当前正在执行其构造函数时,该保证不再成立。

作为替代方案,您可以延迟构造ClassAHandler对象,直到它首次需要为止(例如,通过在该属性的getter中进行延迟初始化)。

这个页面有一个非常好的解释,为什么让“this”引用转义是一个坏主意:

http://www.ibm.com/developerworks/java/library/j-jtp0618.html#2

检查“不要发布”这个“施工期间的参考”部分

创建registerHandler(ClassA处理程序)方法。

没有办法为处理程序不知道的东西创建处理程序。

您可以使用内部类,然后在两个实例之间存在隐式父子关系。 (但我不知道它是否真的更好)。

 public class ClassA { private boolean ClassAattr = false; public class ClassAHandler extends GeneralHandler { public ClassAHandler() { // can access ClassAattr } } public ClassA() { ClassAHandler handler = new ClassAHandler(); } } 

如果传递this ,子类将需要使用parent.classAattr访问父值。 根据demeter定律,我们可以想知道它是否正确。

另一个选择是ClassA传递ClassAHandler在构造函数中需要的所有信息。 如果处理程序需要ClassAttr的值, ClassAttr在构造函数中传递它。

  public ClassA() { ClassAHandler handler = new ClassAHandler( classAattr ); } 

但是参数是按值传递的,所以我不知道它是否适合你。

第三种选择是稍微改变设计并将boolean放在处理程序中。 然后ClassA使用ClassA访问子级的值。 孩子对父母一无所知,但是父母可以在他想要的孩子中获得尽可能多的信息。 这对demeter定律更好。

 public class ClassAHandler extends GeneralHandler { boolean handlerAttr; public ClassAHandler() { } } 
 public class ClassA { private boolean ClassAattr = false; public ClassA() { ClassAHandler handler = new ClassAHandler(this); classAttr = true; } } public class ClassAHandler extends GeneralHandler { ClassA ca = null; public ClassAHandler(ClassA classa) { this.ca = classa; System.out.println(ca.classAttr); } } 

所以我添加了语句classAttr = true;

System.out.println语句将打印false 。 这是因为那时ClassA的构建还不完整。

所以我的建议是在classA添加另一个方法,它将创建ClassAHandler ,然后classAHandler将接收完全构造的ClassA对象

所以代码看起来像。

 public class ClassA { private boolean ClassAattr = false; public ClassA() { classAttr = true; } public init() { ClassAHandler handler = new ClassAHandler(this); } } 

因此代码序列将是new ClassA().init()并且将完美地工作

如果我理解正确,你需要处理程序引用ClassA ,但是你不想在ClassA的构造函数中设置它? 如果是这种情况,那么您可以使用工厂模式将构造与“连线”分开,这将阻止您的ClassA需要了解ClassAHandler类。 有点像这样:

 public class ClassA { private boolean ClassAattr = false; public ClassA() { } } public class ClassAHandler { private ClassA ca = null; public ClassAHandler(ClassA classa) { this.ca = classa; } } public HandlerFactory { public ClassAHandler createClassAHandler(ClassA classa) { ClassAHandler handler = new ClassAHandler(classa); return handler; } } 

为ClassAattr写一个getter方法,如

  public boolean isClassAattr(){ return this.ClassAattr; } 

这样你就可以像ca.isClassAattr()那样访问它;

您可以将ClassAHandler作为ClassA的内部类。 它可以访问ClassA的成员。

您粘贴的代码没有任何问题,但是您可以使用非静态内部类来使事物(可以说)更清洁:

 public class ClassA { private boolean ClassAattr = false; public ClassA() { ClassAHandler handler = new ClassAHandler(); } class ClassAHandler extends GeneralHandler { // magically sees the instantiating ClassA members and methods } } 

prevNode.nex=this是什么意思?

 public class DynamicList { private class Node { Object element; Node next; Node(Object element, Node prevNode) { this.element = element; prevNode.next = this; } }