final关键字

1.      Final variable

(1)    只能在定义final变量的时候,或者在构造器中完成初始化

(2)    对于基本类型,一旦初始化完成了,就不能改变

(3)    对于引用类型,一旦初始化完成了,引用只能指向这个对象;引用不能变,但是对象中的状态能变

(4)    常量,用 public static final修饰的变量代表是常量。常量只能在定义的时候完成初始化,也就是说在class文件编译的时候完成初始化工作的;public表示在全局访问,static表示变量只有一份,final表示一旦初始化后值不能改变

(5)    对于field用public final定义的时候,只能在定义的时候,或者在构造器中初始化,

一旦初始化完成后就不能改变了。

         例如:

         package finalkeyword;

 

public class FinalVariable {

  //常量

  public static final int f1 = 2;

 

  //final reference

  private final Value v;

 

  //

  private final int i;

 

  public FinalVariable(int i,Value v) {

     this.i = i;

     this.v = v;

  }

 

 

 

  public static void main(String[]args){

     Value v1 = new Value(1);

     FinalVariable f= new FinalVariable(2,v1);

     //一旦构造器完成对final基本类型i完成初始化,在其他地方就不能改变了

      //f.i = 9;

     System.out.println(v1.getV1());

     v1.setV1(66);

     //final 引用指向的对象状态可以被改变

     System.out.println(v1.getV1());

     //常量不能动态改变,在class文件编译的时候值已经有了

     //f.f1 = 3;

  }

}

 

2.      Final作为方法的参数

Final variable作为方法的参数,表示方法参数不能再方法中重新赋值

例如:

public void method1(final int j){

       //不能给参数重新赋值

       j = 2;

}

 

3. Final fields在聚集和组合中的运用

(1)聚集

聚集表示了对象之间有一种整体和部分的关系,整体不能脱离部分。具体上来说整体对象和部分对象的生命周期是一样的。不能有整体,而没部分。比如说Car类的对象,一定有Engine对象,它们之间的关系是整体与部分的关系。

Engine类的对象可以在定义的时候,就完成初始化工作;或者必须在Car的构造器中完成对Engine类初始化工作。

所以这时候用final关键字来修饰Engine fields就比较合适了(因为final fields能保证在定义的时候完成初始化,或者在构造器中完成初始化)。

public class Car {

    private final Engine engine;

   

    public Car() {

       engine = new Engine();

    }

 

}

(2)组合

组合是一种弱关联的关系,对象之间的关系在构造器中建立关联,也可以通过方法参数的形式建立关联。

 

(3)Final fields的局限性

Final 引用如果指向的是引用类型,表示这个引用只能只向这个对象,不能指向其他对象;但是引用指向的对象的状态还是可以改变的。如果,我们想构建一个线程安全的不可变类,我们必须保证final引用指向的数组或者可变对象不能从我们的类中逸出。

例如:

package finalkeyword;

 

/**

 *

 * @author Administrator

 *  试图构建不可变对象,但是因为没有正确发布states

 *  导致线程可以去改变states中的元素

 */

public class DangerousStates {

   

    private final String[] states = {"hua","zhang","liu"};

   

    //没有正确发布states,导致states数组中的元素可以被改变。

    public String[] getStates() {

       return states;

    }

   

    public void printStates() {

       for(String s : states)

           System.out.println(s);

    }

   

    public static void main(String[] args){

       DangerousStates d = new DangerousStates();

       String[] s1 = d.getStates();

       //可以改变states[0]指向的字符串。

       s1[0] = "dd";

       d.printStates();

    }

 

}

我们可以克隆数组对象或者用一个不可修改的list来修正这类错误。

package finalkeyword;

 

import java.util.AbstractList;

import java.util.List;

 

public class SafeStates {

    private final String[] states = {"hua","zhang","liu"};

   

    //将数组转为list

    private final List<String> aList = new AbstractList<String>(){

 

       @Override

       public String get(int index) {

          

           return states[index];

       }

 

       @Override

       public int size() {

           // TODO Auto-generatedmethod stub

           return states.length;

       }

      

    };

   

    public List<String> getStateList() {

       return aList;

    }

   

    public void printStates() {

       for(String s : states)

           System.out.println(s);

    }

   

    //1.clone方法修正,不正确发布states

    public String[] getStates1() {

       return states.clone();

    }

   

   

    public static void main(String[] args){

       SafeStates s = new SafeStates();

       String[] s1 = s.getStates1();

       s1[0] = "dd";

       s.printStates();

      

       List<String> l = s.getStateList();

       l.add("d");

       System.out.println(l);

    }

   

}

 

4. Final Method

Final修饰在method上,那么子类就不能override这个方法。

(1)Final method在模版模式中的使用

publicabstract class AbstractBase

{

publicfinal void performOperation() // cannot be overridden

{

prepareForOperation();

doPerformOperation();

}

protectedabstract void doPerformOperation(); // must override

}

模版模式允许基类把部分的算法委托给子类去实现。定义一个final的方法,同时定义一个abstract的方法,定义了基类和子类之间的一种规则,明确的告诉子类去到底哪个方法需要实现。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值