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

时间:2010-03-10 18:17:06

标签: java constructor 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;
    }
}

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

10 个答案:

答案 0 :(得分:11)

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

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

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

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

答案 1 :(得分:4)

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

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

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

答案 2 :(得分:3)

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

无法为处理程序不知道的事情创建处理程序。

答案 3 :(得分:3)

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

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访问父值。根据{{​​3}},我们可以想知道它是否正确。

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

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

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

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

public class ClassAHandler extends GeneralHandler {     
   boolean handlerAttr;

   public ClassAHandler() {       
   }
}

答案 4 :(得分:1)

如果我理解正确,您需要处理程序引用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;
    }

}

答案 5 :(得分:1)

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 ,然后 {{1} } 将收到完全构造的 classAHandler 对象

这样代码看起来就像。

ClassA

这样代码序列将是public class ClassA { private boolean ClassAattr = false; public ClassA() { classAttr = true; } public init() { ClassAHandler handler = new ClassAHandler(this); } } 并将完美地工作

答案 6 :(得分:0)

为ClassAattr编写一个getter方法,如

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

这样你就可以像ca.isClassAattr();

那样访问它

答案 7 :(得分:0)

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

答案 8 :(得分:0)

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

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
    }
}

答案 9 :(得分:0)

prevNode.nex=this这是什么意思?

public class DynamicList {
  private class Node { 
    Object element; 
    Node next; 

    Node(Object element, Node prevNode) { 
      this.element = element; 
      prevNode.next = this; 
    }
}