请选择 进入手机版 | 继续访问电脑版
设为首页收藏本站

猿媛之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 3558|回复: 0

Java-不可变量

[复制链接]

44

主题

48

帖子

198

积分

注册会员

Rank: 2

积分
198
发表于 2016-1-10 22:56:10 | 显示全部楼层 |阅读模式

不可变类(Immutable class)是指当创建了这个类的实例后,就不允许修改它的值,也就是说一个对象一旦被创建出来,在整个生命周期中,它的成员变量就不能被修改了。有点类似常量,只想让别的程序只读。在java类库中,所有基本类型的包装类都是不可变类,如Integer,Float。此外String也是不可变类。可能有人会有疑问,既然String是不可变类,为什么我们还可以写出如下代码来修改String类型的值呢。

  
public class Test {
  
      public static void  main(String[] args) {   
  
            String  s="Hello";
  
            s+=" world";
  
            System.out.println(s);
  
      }
  
}
  
            程序运行结果为
  
Hello world
  
        从表面上看,好像是我们修改String类型对象s的值。其实不是,String s=”Hello”,这句代码声明了一个可以指向String类型对象的引用,这个引用的名字为s,这个引用指向了一个字符串常量”Hello”。s+="world"并没有改变s所指向的对象(由于”Hello”是String类型的对象,而String又是不可变量),这句代码运行后s指向了另外一个String类型的对象,这个对象的内容为”Helloworld”。原来的那个字符串常量”Hello”还存在与内存中,并没有被改变。
        在介绍完不可变类的基本概念后,下面主要介绍如何创建一个不可变类。通常来讲,要创建一个不可变类需要遵循下面四条基本原则:
        1. 类中所有的成员变量被private所修饰。
        2. 类中没有写或者修改成员变量的方法,例如:setxxx。只提供构造函数,一次生成,永不改变。
        3. 确保类中所有的方法不会被子类覆盖,可以通过把类定义为final或者把类中的方法定义为final来达到这个目的。
        4. 如果一个类成员不是不可变量,那么在成员初始化或者使用get方法获取该成员变量是需要通过clone方法,来确保类的不可变性。
        5. 如果有必要,覆盖Object类的equals()和hashCode()方法。在equals()方法中根据对象的属性值来比较两个对象是否相等,并且保证用equals()方法判断为相等的两个对象的hashCode()方法的返回值也相等,这可以保证这些对象能正确地放到HashMap或HashSet集合中。
        除此之外,还有一些小的注意事项:由于类的不可变性,在创建对象的时候就需要初始化所有的成员变量,因此最好提供一个带参数的构造函数来初始化这些成员变量。下面给出一个不可变类的例子。
        下面通过给出一个错误的实现方法与正确的实现方法来说明在实现这种类的时候需要特别注意的问题。首先给出一个错误的实现方法如下:
  
import  java.util.Date;
  
class  ImmutableClass{
  
      private Date d;
  
      public ImmutableClass(Date d){
  
            this.d=d;
  
      }
  
      public void printState(){
  
            System.out.println(d);
  
      }
  
}
  
  
public class TestImmutable{
  
      public static void  main(String[] args){
  
            Date  d=new Date();
  
            ImmutableClass  immuC=new  ImmutableClass(d);
  
            immuC.printState();
  
            d.setMonth(5);
  
            immuC.printState();
  
      }
  
}
  
运行结果:
  
Sun Aug 04 17:41:47 CST 2013
  
Tue Jun 04 17:41:47 CST 2013
说明:由于Date的对象的状态是可以被改变的,而ImmutableClass保存了Date类型对象的引用,当被引用的对象的状态改变的时候会导致ImmutableClass对象状态的改变。
            正确的实现方法如下:

  
import  java.util.ArrayList;
  
import  java.util.Date;
  
  
class  ImmutableClass{
  
      private Date d;
  
      public ImmutableClass(Date d){
  
            this.d=new  Date(d.getTime()); //解除了引用关系
  
      }
  
      public void printState(){
  
            System.out.println(d);
  
      }
  
    public Date  getDate(){
  
            return new Date(d.getTime());
  
      }
  
}
  
public class TestImmutable{
  
      public static void  main(String[] args){
  
            Date  d=new Date();
  
            ImmutableClass  immuC=new  ImmutableClass(d);
  
            immuC.printState();
  
            d.setMonth(5);
  
            immuC.printState();
  
      }
  
}
  
    运行结果:
  
Sun Aug 04 17:47:03 CST 2013
  
Sun Aug 04 17:47:03 CST 2013
        Java语言里面之所以设计有很多不可变类,主要是因为不可变类具有简单、线程安全、节省内存等优点,但凡事有利就有弊,例如,不可变的对象会因为值的不同而生产新的对象,从而导致无法预料的问题,所以,切不可滥用这种模式。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|猿媛之家    

GMT+8, 2020-2-28 13:55 , Processed in 0.212667 second(s), 27 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表