不要在构造函数里往外传this参数



Don't pass 'this' out of a constructor


在一个类例,this关键字指向一个native对象,当前类的实例。在一个构造函数里,this一般有以下几种使用方式.
1. 在第一行,用this(...)调用其他构造函数
2. 用this.filedName的形式访问设置属性
3. 给其他对象的方法当参数,比如blah.operation(this);
最后一种方式会可能导致麻烦,问题是这样的,在构造函数里,当前对象是没有构造完的。一个构造完整的对象是在构造函数返回后的对象,而不返回之前。而当我们
传参数的时候,this指向的应该是一个完全构造好了的对象。


问题常常发生在listener模式上,下面就是个例子:


import java.util.Observable;
import java.util.Observer;


/**
 @author javapractices.com
 @author Andrew Sackett
*/
public final class EscapingThisReference {


  /** 广播站被其他人监听. */
  static final class RadioStation extends Observable {
    //elided
  }
  
  /** 
   A listener which waits until this object is fully-formed before
   it lets it be referenced by the outside world.
   Uses a private constructor to first build the object, and then 
   configures the fully-formed object as a listener. 
  */
  static final class GoodListener implements Observer {
    /** Factory method. */
    static GoodListener buildListener(String aPersonsName, RadioStation aStation){
      //first call the private constructor
      GoodListener result = new GoodListener(aPersonsName);
      //the 'result' object is now fully constructed, and can now be
      //passed safely to the outside world
      aStation.addObserver(result);
      return result;
    }
    @Override public void update(Observable aStation, Object aData) {
      //..elided
    }
    private String fPersonsName;
    /** Private constructor. */
    private GoodListener(String aPersonsName){
      this.fPersonsName = aPersonsName; //ok
    }
  }
  
  /** 
   A listener which incorrectly passes a 'this' reference to the outside world 
   before construction is completed.
  */
  static final class BadListenerExplicit implements Observer {
    /** Ordinary constructor. */
    BadListenerExplicit(String aPersonsName, RadioStation aStation){
      this.fPersonsName = aPersonsName; //OK
      //DANGEROUS - the 'this' reference shouldn't be passed to the listener,
      //since the constructor hasn't yet completed; it doesn't matter if 
      //this is the last statement in the constructor!
      aStation.addObserver(this);
    }
    @Override public void update(Observable aStation, Object aData) {
      //..elided
    }
    private String fPersonsName;
  }
  
  /** 
   Another listener that passes out a 'this' reference to the outside 
   world before construction is completed; here, the 'this' reference 
   is implicit, via the anonymous inner class.
  */
  static final class BadListenerImplicit {
    /** Ordinary constructor. */
    BadListenerImplicit(String aPersonsName, RadioStation aStation){
      this.fPersonsName = aPersonsName; //OK
      //DANGEROUS
      aStation.addObserver(
        new Observer(){
          @Override public void update(Observable aObservable, Object aData) {
            doSomethingUseful();
          }
        }
      );
    }
    private void doSomethingUseful() {
      //..elided
    }
    private String fPersonsName;
  }
}
 





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值