Java_final关键字,不可变类,缓存不可变类实例(缓存池技术)

本文详细介绍了Java中final关键字的使用方法,包括final变量、方法和类的特点,如何创建不可变类及其实例缓存策略。

1. final变量:final修饰的变量一旦获得了初始值之后就不可被改变。final可以修饰成员变量,局部变量,形参。

1.1 final成员变量:final修饰的类属性(static)可以在静态初始化块或声明时指定初始值;final修饰的实例属性可以在非静态初始化块,构造器或声明时指定初始值。

[html]  view plain  copy
 print ?
  1. class TestFinal {  
  2.     final int a = 1;    //声明时指定初始值  
  3.     final int b;  
  4.     final int c;  
  5.     static final String NAME_1 = "MengLei"; //声明时指定初始值  
  6.     static final String NAME_2;  
  7.       
  8.     {  
  9.         b = 2;  //使用非静态初始化块为实例属性b指定初始值  
  10.     }  
  11.     TestFinal() {  
  12.         c = 3;  //使用构造器为实例属性c指定初始值  
  13.     }  
  14.     static {  
  15.         NAME_2 = "MengChen";    //使用静态初始化块为类属性指定初始值  
  16.     }  
  17. }  

1.2 final修饰局部变量:如果final休斯的局部变量在声明时没有指定初始值,则可以在后面代码中指定,但只能一次。

[html]  view plain  copy
 print ?
  1. public class Temp {  
  2.     public static void main(String[] args) {  
  3.         final int a = 1;    //声明时指定初始值  
  4.         final int b;  
  5.         b = 2;  //后来指定初始值  
  6.         b = 3;  //报错:不能重复指定       
  7.     }  
  8.     public void test(final int a) {  
  9.         a = 3;  //报错:不能对final形参赋值  
  10.     }  
  11. }  

1.3 final修饰基本类型变量和引用类型变量的区别:当final修饰基本类型变量时,不能对基本类型变量重新赋值,因此变量值不能被改变;但对于引用变量而言,它保存的仅仅是一个引用,final只保证这个引用不能指向别的地址空间,但是被引用的对象的内容是可以改变的。


2. final方法:final修饰的方法不能被重写。但是可以重载。


3. final类:final修饰的类不可以有子类。


4. 不可变类:创建类的实例后,实例的属性是不可改变的。Java提供的包装类和String类都是不可变类。

[html]  view plain  copy
 print ?
  1. Double d = new Double(1.1);  
  2. String s = new String("ML");  

上面这两个类通过传入的参数实例化各自的对象,但是他们的属性是不可改变的。

如果需要创建自定义的不可变类,需要:

a. 使用private和final修饰成员属性。

b. 提供带参数的构造器,并通过传入的参数初始化成员属性。

c. 仅为类属性提供getter方法,不要提供setter方法。

d. 最好重写Object类的hashCode和equals方法。equals方法根据关键属性作为判断相等的标准,此外还需要保证两个用equals方法判断相等的对象的hashCode也相等。


5. 缓存不可变类实例:不可变类的实例不可改变,可以很方便的被多个对象共享。如果程序经常需要使用相同的不可变类实例,则应该考虑缓存这种不可变类的实例。毕竟多次重复创建相同对象没有太大意义,而且加大了系统开销。

[java]  view plain  copy
 print ?
  1. public class Temp {  
  2.     public static void main(String[] args) {  
  3.         CacheImmutale ci1 = CacheImmutale.valueOf("MengLei");  
  4.         CacheImmutale ci2 = CacheImmutale.valueOf("MengLei");  
  5.         System.out.println(ci1==ci2);   //输出:true,说明两者是同个对象  
  6.     }  
  7. }  
  8.   
  9. class CacheImmutale {  
  10.     private final String name;  
  11.     private static CacheImmutale [] cache = new CacheImmutale [10];   //缓存池,保存10个实例  
  12.     private static int pos = 0;   //记录最新创建的缓存实例在缓存数组中的位置  
  13.       
  14.     public CacheImmutale(String name) {   
  15.         this.name = name;   //name通过构造器指定初始值  
  16.     }  
  17.     public String getName() {  
  18.         return this.name;  
  19.     }  
  20.     public static CacheImmutale valueOf(String value) {  
  21.         for (int i=0;i<pos;i++) {    //遍历缓存对象  
  22.             if (cache[i] != null && cache[i].getName().equals(value)) { //如果发现相同的对象,则返回  
  23.                 return cache[i];  
  24.             }  
  25.         }  
  26.         if (pos == 10) {  
  27.             pos = 0;  
  28.             cache[pos++] = new CacheImmutale(value);    //如果没有在缓存池中发现相同的对象,但缓存池满了,则建立新对象,添加到缓存池的第一个对象(先进先出),并返回该对象  
  29.             return cache[pos-1];  
  30.         }  
  31.         else {  
  32.             cache[pos++] = new CacheImmutale(value);    //如果没有在缓存池中发现相同的对象,而且缓存池也没有满,则建立新对象,添加进缓存池,并返回该对象  
  33.             return cache[pos-1];  
  34.         }  
  35.     }  
  36.     public boolean equals(Object obj) {   //重写equals方法,name属性相等即为相等  
  37.         if (obj instanceof CacheImmutale) {  
  38.             CacheImmutale ci = (CacheImmutale)obj;  
  39.             if (ci.getName().equals(this.getName()))  
  40.                 return true;  
  41.             else  
  42.                 return false;  
  43.         }  
  44.         else  
  45.             return false;  
  46.     }  
  47.     public int hashCode() {   //重写hashCode方法  
  48.         return this.getName().hashCode();  
  49.     }  
  50. }  
java提供的Integer类就采用了这种处理策略,如果用new构造器来创建Integer对象,则每次返回全新的Integer对象;如果用valueOf方法创建Integer对象,则会缓存该方法的创建。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值