java 在java构造函数中传递“this”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2419410/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing "this" in java constructor
提问by Bruno Mello
Look into the following code:
查看以下代码:
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;
}
}
I need to access ClassAattron some ClassAHandlermethods, among other attributes. Is there a way to do so without passing the origin class in the handler constructor. I don't really like how this solution "looks".
我需要访问ClassAattr某些ClassAHandler方法以及其他属性。有没有办法在不传递处理程序构造函数中的原始类的情况下这样做。我真的不喜欢这个解决方案的“外观”。
回答by Joachim Sauer
Passing thisto another method/object from inside the constructor can be rather dangerous. Many guarantees that objects usually fulfill are not necessarily true, when they are looked at from inside the constructor.
this从构造函数内部传递到另一个方法/对象可能相当危险。当从构造函数内部查看时,对象通常实现的许多保证不一定是正确的。
For example if your class has a final(non-static) field, then you can usually depend on it being set to a value and never changing.
例如,如果你的类有一个final(非static)字段,那么你通常可以依赖它被设置为一个值并且永远不会改变。
When the object you look at is currently executing its constructor, then that guarantee no longer holds true.
当您查看的对象当前正在执行其构造函数时,该保证不再成立。
As an alternative you could delay the construction of the ClassAHandlerobject until it is first needed (for example by doing lazy initialization in the getter of that property).
作为替代方案,您可以延迟ClassAHandler对象的构建,直到首次需要它(例如,通过在该属性的 getter 中进行延迟初始化)。
回答by Mark Pope
This page has a very good explanation of why letting the "this" reference escape is a bad idea:
这个页面很好地解释了为什么让“this”引用转义是一个坏主意:
http://www.ibm.com/developerworks/java/library/j-jtp0618.html#2
http://www.ibm.com/developerworks/java/library/j-jtp0618.html#2
Check the "Don't publish the "this" reference during construction" section
检查“在构建过程中不要发布“这个”参考”部分
回答by ewernli
You could use inner classes, there is then a implicit parent-child relationship between the two instances. (But I don't know if it's really better).
您可以使用内部类,然后在两个实例之间存在隐式父子关系。(但我不知道它是否真的更好)。
public class ClassA {
private boolean ClassAattr = false;
public class ClassAHandler extends GeneralHandler {
public ClassAHandler() {
// can access ClassAattr
}
}
public ClassA() {
ClassAHandler handler = new ClassAHandler();
}
}
If you pass this, the subclass will need to access the parent value with parent.classAattr. We can wonder whether it's correct according to the law of demeter.
如果通过this,子类将需要使用 访问父值parent.classAattr。根据得墨忒耳定律,我们可以怀疑它是否正确。
Another option then would be that ClassApass all the information that ClassAHandlerrequires in the constructor. If the handler requires the value of ClassAttr, pass it in the constructor.
另一个选择是ClassA传递ClassAHandler构造函数中所需的所有信息。如果处理程序需要 的值ClassAttr,则在构造函数中传递它。
public ClassA() {
ClassAHandler handler = new ClassAHandler( classAattr );
}
But the parameter is passed by value so I don't know if it works for you.
但是参数是按值传递的,所以我不知道它是否适合你。
A third option would be to change the design a bit and have the booleanbe in the handler. Then ClassAaccesses the value of the child with handler.handlerAttr. The child knows nothing about the parent, but the parent can access as much information in the child has he wants. This is better regarding the law of demeter.
第三种选择是稍微更改设计并将boolean其放在处理程序中。然后ClassA使用 访问孩子的价值handler.handlerAttr。孩子对父母一无所知,但父母可以访问孩子想要的尽可能多的信息。这对于德墨忒耳法则来说更好。
public class ClassAHandler extends GeneralHandler {
boolean handlerAttr;
public ClassAHandler() {
}
}
回答by Morfildur
Create a registerHandler(ClassA handler) method.
创建 registerHandler(ClassA handler) 方法。
There is no way to create a handler for something the handler doesn't know about.
无法为处理程序不知道的内容创建处理程序。
回答by KarstenF
If I understand correctly, you need the handler to have a reference to ClassA, but you don't want to set this up from within the constructor of ClassA?
If that is the case, then you could separate construction from "wiring up" using a factory pattern, which will prevent your ClassAfrom needing to know about the ClassAHandlerclass. Kind of like this:
如果我理解正确,您需要处理程序引用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;
}
}
回答by Jeril Kuruvila
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);
}
}
So I have added the statement classAttr = true;
所以我添加了声明 classAttr = true;
The System.out.printlnstatement will print false.
This is because the construction of ClassAwas not complete at that point.
该System.out.println语句将打印false。这是因为当时的建设ClassA还没有完成。
So my suggestion is to add another method in classAwhich will create the ClassAHandlerand then the classAHandlerwill receive fully constructed ClassAobject
所以我的建议是添加另一种方法,在classA该方法中将创建ClassAHandler然后classAHandler将接收完全构造的 ClassA对象
So that the code will look like.
这样代码就会看起来像。
public class ClassA {
private boolean ClassAattr = false;
public ClassA() {
classAttr = true;
}
public init() {
ClassAHandler handler = new ClassAHandler(this);
}
}
So that the code sequence will be new ClassA().init()and will work perfectly
以便代码序列将new ClassA().init()完美运行
回答by Omry Yadan
there is nothing wrong with the code you pasted, however you can use a non static inner class to make things (arguably) cleaner:
您粘贴的代码没有任何问题,但是您可以使用非静态内部类来使事情(可以说)更干净:
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
}
}
回答by GuruKulki
Write a getter method for ClassAattr, as
为 ClassAattr 编写一个 getter 方法,如
public boolean isClassAattr(){
return this.ClassAattr;
}
So that you can get access it as ca.isClassAattr();
这样你就可以通过 ca.isClassAattr(); 访问它。
回答by Vincent Ramdhanie
You may make ClassAHandler an inner class of ClassA. It would have access to the members of ClassA.
您可以使 ClassAHandler 成为 ClassA 的内部类。它可以访问 ClassA 的成员。

