??xml version="1.0" encoding="utf-8" standalone="yes"?>久久久久一区二区三区四区,日韩一区二区三区中文字幕,亚洲精品乱码日韩http://www.aygfsteel.com/lsbwahaha/archive/2009/12/17/306422.html胡鹏胡鹏Thu, 17 Dec 2009 12:25:00 GMThttp://www.aygfsteel.com/lsbwahaha/archive/2009/12/17/306422.htmlhttp://www.aygfsteel.com/lsbwahaha/comments/306422.htmlhttp://www.aygfsteel.com/lsbwahaha/archive/2009/12/17/306422.html#Feedback0http://www.aygfsteel.com/lsbwahaha/comments/commentRss/306422.htmlhttp://www.aygfsteel.com/lsbwahaha/services/trackbacks/306422.html
q里考虑的是参数多的情况Q如果参C数比较少Q那直接采用一般的构造方法就可以了?/strong>


   书中介绍了写构造方法的时候几U方式:

    1. 重叠构造方法模?
       ~点Q有许多参数的时候,客户端代码会很难写,而且较难以阅诅R?br />
     2. javaBeans模式Q?br />        ~点Q?nbsp; 
            在构造过E中JavaBean可能处于不一致的状态,cLw无法判断是否有效性?br />             cd成不可变的可能?br />
     3. builder模式Q?br />        优点Q?br />             在buildҎ生成对象的时候,可以做检查,判断是否W合要求
            参数灉|
       ~点Q?br />             创徏对象必须先创建构造器Q如果对性能要求非常高的应用用为妙



具体实现代码Q?br /> 1.重叠构造方法模式:
public class NutritionFacts {
    
private final int servingSize;
    
    
private final int serviings;
    
    
private final int calories;
    
    
private final int fat;
    
    
private int sodium;
    
    
private int carbohydrate;
    
    
public NutritionFacts(int servingSize, int serviings){
        
this(servingSize, serviings, 0);
    }
    
    
public NutritionFacts(int servingSize, int serviings, int calories){
        
this(servingSize, serviings, calories, 0);
    }
    
    
public NutritionFacts(int servingSize, int serviings, int calories, int fat){
        
this(servingSize, serviings, calories, fat,0);
    }
    
    
public NutritionFacts(int servingSize, int serviings, int calories, int fat, int sodium){
        
this(servingSize, serviings, calories, fat, sodium,0);
    }
    
    
public NutritionFacts(int servingSize, int serviings, int calories, int fat, int sodium, int carbohydrate){
        
this.servingSize = servingSize;
        
this.serviings = serviings;
        
this.calories = calories;
        
this.fat = fat;
        
this.sodium = sodium;
        
this.carbohydrate = carbohydrate;
    }
}



2. javaBeans模式 代码Q?br />
public class NutritionFacts {
    
private  int servingSize;
    
    
private  int serviings;
    
    
private  int calories;
    
    
private  int fat;
    
    
private int sodium;
    
    
private int carbohydrate;
    
    
public NutritionFacts(){}
    
    
    
public void setServingSize(int servingSize) {
        
this.servingSize = servingSize;
    }

    
public void setServiings(int serviings) {
        
this.serviings = serviings;
    }

    
public void setCalories(int calories) {
        
this.calories = calories;
    }

    
public void setFat(int fat) {
        
this.fat = fat;
    }

    
public void setSodium(int sodium) {
        
this.sodium = sodium;
    }

    
public void setCarbohydrate(int carbohydrate) {
        
this.carbohydrate = carbohydrate;
    }


 3. builder模式

public class NutritionFacts {
    
private final int servingSize;
    
private final int serviings;
    
private final int calories;
    
private final int fat;
    
private final int sodium;
    
private final int carbohydrate;

    
public static class Builder {
        
private final int servingSize;
        
private final int serviings;

        
// 可以为空
        private int calories = 0;
        
private int fat = 0;
        
private int sodium = 0;
        
private int carbohydrate = 0;

        
public Builder(int servingSize, int serviings) {
            
this.servingSize = servingSize;
            
this.serviings = serviings;
        }
        
        
public Builder calories(int val){
            calories 
= val;
            
return this;
        }
        
        
public Builder fat(int val){
            fat 
= val;
            
return this;
        }
        
        
public Builder sodium(int val){
            sodium 
= val;
            
return this;
        }
        
        
public Builder carbohydrate(int val){
            carbohydrate 
= val;
            
return this;
        }
        
        
public NutritionFacts build(){
            
return new NutritionFacts(this);
        }
        
    }

    
public NutritionFacts(Builder builder) {
        servingSize 
= builder.servingSize;
        serviings 
= builder.serviings;
        calories 
= builder.calories;
        fat 
= builder.fat;
        sodium 
= builder.sodium;
        carbohydrate 
= builder.carbohydrate;
    }
}
 q个调用的时候: 
NutritionFacts cocaCola = new NutritionFacts.Builder(11,22).calories(1).fat(2).calories(3).build();





胡鹏 2009-12-17 20:25 发表评论
]]>
诅Reffective java》学习笔Chttp://www.aygfsteel.com/lsbwahaha/archive/2009/07/28/288800.html胡鹏胡鹏Tue, 28 Jul 2009 12:30:00 GMThttp://www.aygfsteel.com/lsbwahaha/archive/2009/07/28/288800.htmlhttp://www.aygfsteel.com/lsbwahaha/comments/288800.htmlhttp://www.aygfsteel.com/lsbwahaha/archive/2009/07/28/288800.html#Feedback0http://www.aygfsteel.com/lsbwahaha/comments/commentRss/288800.htmlhttp://www.aygfsteel.com/lsbwahaha/services/trackbacks/288800.htmlW六?在改写equals的时候请遵守通用规定
  有一U?#8220;值类”可以不要求改写equalsҎQ类型安全枚丄型,因ؓcd安全枚Dcd保证每一个g多只存在一个对象,所有对于这Lc而言QObject的quealsҎ{同于逻辑意义上的equalsҎ?br />  
  在改写equalsҎ的时候,要遵循的规范Q?nbsp;
        1Q自反性?/span>对Q意的引用值x,x.equals(x)一定是true
        2Q对U性?/span>对于L的引用值x和y,当且仅当y.equals(x)q回trueӞx.equals(y)也一定返回true.
        3Q传递性?/span>对于L的引用值x,y和z,如果x.equals(y)==true and y.equals(z)==true,so x.equals(z)==true.
        4Q一致性?/span>对于L的引用值x和y,如果用于equals比较的对象信息没有被修改的话Q那么,多次调用x.equals(y)要么一致地q回true,要么一致地q回false.
        5Q非I性?/span>对于L的非I引用值x,x.equals(null)一定返回false.
        
  自反性:要求一个对象必ȝ于其自n。一个例子:你把该类的实例加入到一个集合中Q则该集合的containsҎ
果断地告诉你,该集合不包含你刚刚加入的实例Q?nbsp;

  对称性:
  例如Q?br />      public final class CaseInsensitiveString{
           private String s;
           public CaseInsensitiveString(String s){
              if(s==null)   throw new NullPointerException();
              this.s=s;
           }
           public boolean equals(Object o){
              if(o instanceof CaseInsensitiveString)
                 return s.equalsIgnoreCase(((CaseInsensitiveString)o).s);
              if(o instanceof String)
                 return s.equalsIgnoreCase((String)o);
               return false;
            }
          }
调用Q?br />    CaseInsensitiveString cis=new CaseInsensitiveString("Polish");
       String s="polish";
正如我们期望的:cis.equals(s)==true but s.equals(cis)==false
q就q反了对U性的原则Qؓ了解册个问题,只需把企图与String互操作的q段代码从equalsҎ中去掉旧可以了.q样做之后,你可以重构代码,使他变成一条返回语句:
public boolean equals(Object o){
   return o instanceof CaseInsensitiveString && ((CaseInsensitiveString)o).s.equalsIgnoreCase(s);
}

 

传递?/span>---卛_果一个对象等于第二个对象Qƈ且第二个对象又等于第三个对象Q则W一个对象一定等于第三个对象?br /> 例如Q?br />        public class Point{
           private final int x;
           private final int y;
           public Point(int x,int y){
                this.x=x;
                this.y=y;
          }
          public boolean equals(Object o){
             if(!(o instanceof Point))
              return false;
             Point p=(Point)o;
             return p.x==x&&p.y==y;
          }
     }
现在我们来扩展这个类Qؓ一个点增加颜色信息Q?br />    public class ColorPoint extends Point{
      private Color color;
      public ColorPoint(int x,int y,Color color){
          super(x,y);
          this.color=color;
      }
   }
分析Q?equalsҎ会怎么样呢Q如果你完全不提供equalsҎQ而是直接从Pointl承q来Q那么在equals座比较的时候颜色信息会被忽略掉。如果你~写一个equalsҎQ只有当实参是另一个有色点Qƈ且具有同L位置和颜色的时候,它才q回true:
       public boolean equals(Object o){
          if(!(o instanceof ColorPoint)) return false;
          ColorPoint cp=(ColorPoint)o;
          return super.equals(o) && cp.color==color;
       }
分析Q这个方法的问题在于Q我们在比较一个普通点和一个有色点Q以及反q来的情形的时候,可能会得C同的l果。前一U比较忽略了颜色信息Q而后一U比较Lq回false,因ؓ实参的类型不正确。例如:
     Point p=new Point(1,2);
     ColorPoint cp=new ColorPoint(1,2,Color.RED);
然后Qp.equals(cp)==true but cp.equals(p)==false

修正Q让ColorPoint.equals在进?#8220;混合比较”的时候忽略颜色信息:
   public boolean equals(Object o){
       if(!(o instanceof Point)) return false;
       if(!(o instanceof ColorPoint)) return o.equals(this);
       ColorPoint cp=(ColorPoint)o;
       return super.equals(o) && cp.color==color;
   }
q种Ҏ实提供了对U?但是却牺牲了传递?
   ColorPoint p1=new ColorPoint(1,2,Color.RED);
   Point p2=new Point(1,2);
   ColorPoint p3=new ColorPoint(1,2,Color.BLUE);
此时Qp1.equals(p2)==true and p2.equals(p3)==true but p1.equals(p3)==false很显然违反了传递性。前两个比较不考虑颜色信息Q而第三个比较考虑了颜色信息?/p>

l论Q要惛_扩展一个可实例华的cȝ同时Q既要增加新的特征,同时q要保留equalsU定Q没有一个简单的办法可以做到q一炏V?span style="color: red">Ҏ"复合优于l承"Q这个问题还是有好的解决办法Q我们不让ColorPoint扩展PointQ而是在ColorPoint中加入一个私有的Point域,以及一个公有的视图ҎQ此Ҏq回一个与该有?点在同一位置上的普通Point对象Q?br />     public class ColorPoint{
       private Point point;
       private Color color;
       public ColorPoint(int x,int y,Color color){
         point=new Point(x,y);
         this.color=color;
       }
       public Point asPoint(){
           return point;
       }
     
       public boolean equals(Object o){
           if(!(o instanceof ColorPoint)) return false;
           ColorPoint cp=(ColorPoint)o;
           return cp.point.equals.(point) && cp.color.equals(color);
       }
    }
   
注意Q你可以在一个抽象类的子cM增加新的特征Q而不会违反equalsU定?/p>

 

一致?
 如果两个对象相等的话Q那么它们必dl保持相{,除非有一个对象被修改了。由于可变对象在不同的时候可以与不同的对象相{,而非可变对象不会q样Q这个约定没有严格界定?br />  


非空?没什么好说的?/p>

1Q?=操作W检?#8220;实参是否为指向对象的一个应?#8221;。如果是的话Q则q回true?br />        2Q用instanceof操作W检?#8220;实参是否为正的cd”。如果不是的话,则返回false?br />        3Q把实参转换到正的cd?br />        4Q对于该cM每一?#8220;关键QsignificantQ?#8221;域,查实参中的域与当前对象中对应的域值是否匹?br />      if (!(this.field == null ? o.field == null : this.equals(o.field)))
     //或者写?if(!(this.field == o.field || (this.field != null && this.field.equals(o.field)))) 对于this.field和o.field通常是相同的对象引用Q会更快一些?br />        return false;
     //比较下一个field
     //都比较完?br />      return true;
     
5.最后还要确认以下事?br />    5.1Q改写equals的同ӞLQ必)要改写hashCodeҎQ见【第8条】)Q这是极Ҏ被忽略的Q有极ؓ重要?br />    5.2Q不要企图让equalsҎq于聪明
   5.3Q不要用不可靠的资源。如依赖|络q接
   5.4Q不要将equals声明中的Object对象替换为其他类型?br />          public boolean equals(MyClass) q样的声明ƈ不鲜见,往外ɽE序员数时搞不清楚Z么不能正常工?br />          原因是这里是重蝲QoverloadQ而ƈ不是改写QoverrideQ(或称盖、重写)
         相当于给equals又增加了一个实参类型ؓMyClass的重载,而实参ؓObject的那个equalsq没有被改写Q依然还是从Objectl承来的最初的那个equalsQ所L看不到程序员惌的效果。因为类库或其他人写的代码都是调用实参ؓObject型的那个equalsҎ的(别h又如何在事前知晓你今天写的MyClass呢?Q?br />



胡鹏 2009-07-28 20:30 发表评论
]]>
诅Reffective java》学习笔Chttp://www.aygfsteel.com/lsbwahaha/archive/2009/07/23/288079.html胡鹏胡鹏Thu, 23 Jul 2009 11:31:00 GMThttp://www.aygfsteel.com/lsbwahaha/archive/2009/07/23/288079.htmlhttp://www.aygfsteel.com/lsbwahaha/comments/288079.htmlhttp://www.aygfsteel.com/lsbwahaha/archive/2009/07/23/288079.html#Feedback0http://www.aygfsteel.com/lsbwahaha/comments/commentRss/288079.htmlhttp://www.aygfsteel.com/lsbwahaha/services/trackbacks/288079.html           每天下班q旉学习下吧Q尽量在一个星期内把它看完Qȝ出来Q大多数内容都来自书上,个h觉得该书不错的地Ҏ出来?br />
 W一条:考虑用静态工厂方法代替构造函?br />     静态工厂方?优点)Q?br />          1.每次调用的时候,不一定要创徏一个新的对象,q个可以自由控制?br />          2.它可以返回一个原q回cd的子cd的对象?br />

 
W二条:使用U有构造函数强化singleton属?/span>
W一U:提供共有的静态final?br />

public class Elvis{
 
public static final Elvis INSTANCE = new Elvis();
 
private Elvis(){
    
 }

 
}

 

W二U:提供一个共有的静态工厂方?/strong>

 1public class Elvis{
 2 private static final Elvis INSTANCE = new Elvis();
 3 private Elvis(){
 4    
 5 }

 6 
 7 public static Elvis getInstance(){
 8  return INSTANCE;
 9 }

10 
11}

 

W一U性能上会E微好些
W二U提供了灉|性,在不改变API的前提下Q允许我们改变想法,把该cd成singletonQ或者不做,Ҏ被修攏V?/font>

注意点:Z使一个singletoncd成克序列q(Serializable),仅仅在声明中加上implements Serializable是不够的Q?br /> Zl护singleton性,必须也要提供一?
private Object readResolve() throws ObjectStreamException{
 return INSTANCE;
}


W三条:通过U有构造函数强化不可实例化的能?/span>
只要让这个类包含单个昑ּ的私有构造函敎ͼ则它׃可被实例?

1 public class UtilityClass{
2  private UtilityClass(){
3   
4  }
5  
6 }

 

企图通过一个类做成抽象cL强制该类不可被实例化Q这是行不通的。该cd以被子类化,q且该子cM可以被实例化?br /> 更进一步,q样做会误导用户Q以U类是专门ؓ了承而设计的?/p>

 

W四条:避免创徏重复的对?/span>
String s  = new Sting("silly");//q么恶心的代码就不要写啦。。?/p>

1.静态工厂方法可几乎L优先于构造方?Boolean.valueOf(...) > Boolean(...),构造函数每ơ被调用的时候都会创Z个新的对象,
而静态工厂方法从来不要求q样做?/p>

2.

public class Person {
    
private final Date birthDate;
    
    
public Person(Date date){
        
this.birthDate = date;
    }

    
    
//don't do this
    public boolean isBabyBoomer(){
        Calendar gmtCal 
= Calendar.getInstance(TimeZone.getTimeZone("GMT"));
        gmtCal.set(
1946,Calendar.JANUARY,1,0,0,0);
        Date boomStart 
= gmtCal.getTime();
        gmtCal.set(
1965,Calendar.JANUARY,1,0,0,0);
        Date boomEnd 
= gmtCal.getTime();
        
return birthDate.compareTo(boomStart) >=0 && birthDate.compareTo(boomEnd) <0;
    }

}

 

 

isBabyBoomer每次被调用的时候,都会创徏一个新的CalendarQ一个新的TimeZone和两个新的Date实例。。?/p>

下面的版本避免了q种低效率的动作Q代之以一个static 块初始化Calendar对象Q而且最体现效率的是Q他的生命周期只实例化一ơCalendarq且?br /> 80q_90q的出生的D值给c静态变量BOOM_START和BOOM_END

class Person {
 
private final Date birthDate;

 
public Person(Date birthDate) {
  
this.birthDate = birthDate;
 }


 
 
private static final Date BOOM_START;
 
private static final Date BOOM_END;
 
static {
  Calendar gmtCal 
= Calendar.getInstance(TimeZone.getTimeZone("GMT"));
  gmtCal.set(
1980, Calendar.JANUARY, 1000);
  BOOM_START 
= gmtCal.getTime();
  gmtCal.set(
1990, Calendar.JANUARY, 1000);
  BOOM_END 
= gmtCal.getTime();
 }


 
public boolean isBabyBoomer() {
  
return birthDate.compareTo(BOOM_START) >= 0
    
&& birthDate.compareTo(BOOM_END) < 0;
 }


 

 


 



胡鹏 2009-07-23 19:31 发表评论
]]>
վ֩ģ壺 | | | Դ| | | | | ʯȪ| | Ϫ| ͭϿ| ذ| | | | | | | ʹ| ϴ| ɽ| ̨| | ǫ| ̨| | | | µ| Dz| ˶| | ˮ| | ͨ| | 㽭ʡ| Դ| | ɽ|