不可变类是指创建类的对象实例后,该实例的属性不能发生改变。常见的String就是不可变类。不可变类型的属性值不会发生改变,这在多线程编程的时候非常有用,不用担心对象的属性值被修改。

下面我们来看看如何实现一个不可变类型:

1.要保证属性值不发生改变,属性必须用private和final修饰。

2.要在类的构造函数中初始化final属性,并且只提供getter方法,不提供setter方法。

3.重写equals和hashCode,使用重写的equals方法根据属性值判断两个对象是否相等,hashCode方法保证不同的对象,hashCode不同。

最简单的不可变类实现方法:

classPerson

{privatefinal String firstName;privatefinal String lastName;publicPerson(String firstName,String lastName)

{this.firstName=firstName;this.lastName=lastName;

}publicString getFirstName()

{returnfirstName;

}publicString getLastName()

{returnlastName;

}

@Overridepublicboolean equals(Object obj)

{if(obj instanceof Person)

{

Person p=(Person)obj;return this.firstName.equals(p.firstName)&&this.lastName.equals(p.lastName);

}else{throw newClassCastException();

}

}

@Overridepublic inthashCode()

{return (this.firstName+this.lastName).hashCode();

}

}

Person类就是一个不可变类,属性都是private和final类型,并且只提供了getter方法,根本无法修改属性的值。

但是如果一个类中包含了一个可变类型那就不能这么简单的实现了。

className

{privateString firstName;privateString lastName;publicName() {}publicName(String firstName, String lastName)

{this.setFirstName(firstName);this.setLastName(lastName);

}publicString getFirstName() {returnfirstName;

}public voidsetFirstName(String firstName) {this.firstName =firstName;

}publicString getLastName()

{returnlastName;

}public voidsetLastName(String lastName)

{this.lastName =lastName;

}

}classPerson

{privatefinal Name name;publicPerson(Name name)

{this.name=name;

}publicName getName()

{returnname;

}

@OverridepublicString toString()

{return name.getFirstName()+"$"+name.getLastName();

}

}

Person类中含有一个可变类型Name,虽然Name被final和private修饰,并且只有getter,但是仍然可以修改Name的值:

Person person=new Person(new Name("Hello","world"));

System.out.println(person);

person.getName().setFirstName("hel");

System.out.println(person);

输出结果:

Hello$world

hel$world

很明显不能达到不可变类的目的,要想变成不可变类,需要在getter中返回一个新的对象,在构造器中也要用新的对象初始化:

publicPerson(Name name)

{this.name=newName(name.getFirstName(),name.getLastName());

}publicName getName()

{return newName(name.getFirstName(),name.getLastName());

}

这样就完全不会改变对象实例的值了。String类就是使用了类似的实现方法,不过使用的常量缓存池,大大提高了性能。每次初始化String对象是都会先检查常量缓存池,如果已经存在则不会再内存中创建新的常量字符串了。

java 可变 不可变_java中的不可变类型的探究相关推荐

  1. java string字节大小_Java中char[] 和 String 类型占用字节大小问题

    作者:威威喵 原文链接:https://blog.csdn.net/smile_Running/article/details/87211916 在 C 语言中 1.char a[10] = {&qu ...

  2. java比较时间戳大小_JAVA中两个String类型的时间戳怎么样比较大小?

    1.从数据库里面获得的时间戳是String类型的,要与当前时间比较,判断登陆是否过期 生成一long类型的当前时间,把String类型强制转换成long类型报错,代码如下: long currentT ...

  3. java函数式编程入口_Java中的函数式编程

    前言 JDK8引入的Lambda表达式和Stream为Java平台提供了函数式编程的支持,极大地提高了开发效率.本文结合网络资源和自身使用经验,介绍下Java中的函数式编程 Java中的函数式编程 出 ...

  4. java可以多重继承吗_Java中的多重继承与组合vs继承

    java可以多重继承吗 有时我写了几篇有关Java继承,接口和组成的文章. 在这篇文章中,我们将研究多重继承,然后了解组成优于继承的好处. Java中的多重继承 多重继承是创建具有多个超类的单个类的能 ...

  5. java中有没有栈_Java中堆和栈有什么区别

    stack 和 heep 都是内存的一部分stack 空间小,速度比较快, 用来放对象的引用heep 大,一般所有创建的对象都放在这里.栈(stack):是一个先进后出的数据结构,通常用于保存方法(函 ...

  6. java包装器类_Java中的基本类型和包装类

    Java中基本数据类型与包装类型有 基本类型 包装器类型 boolean Boolean char Character int Integer byte Byte short Short long L ...

  7. java 基本类型 引用_java中 引用类型 和 基本类型 有何区别?

    栈与堆都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. Java的堆是一个运行时数据区,类的(对象从中分配空间.这些对象通过new.newa ...

  8. java 验证码透明背景_Java中的证书透明度验证

    java 验证码透明背景 因此,我有一个幼稚的想法,即除了证书有效性检查(在Java中)之外,将证书透明性验证作为每个请求的一部分也很容易. 牺牲了整个周末的一半时间,我可以证明这并不是一件小事. 但 ...

  9. java构造器详解_Java中关于构造器的使用详解

    这篇文章主要介绍了Java构造器使用方法及注意事项的相关资料,这里举例说明如何使用构造器及需要注意的地方,需要的朋友可以参考下 Java构造器使用方法及注意事项 超类的构造器在子类的构造器运行之前运行 ...

最新文章

  1. java值参_Java陷阱之慎用入参做返回值详解
  2. crt脚本怎么添加等待时间_secureCRT自动化脚本(之定时任务)
  3. 广州电子厂房净化工程_简述设计电子车间净化工程的注意要点
  4. yeomanbower
  5. python独立环境——virtualenv
  6. c#中高效的excel导入oracle的方法
  7. SLAM_信息矩阵协方差矩阵
  8. 解决电脑右键新建没有文本文档的问题
  9. SoapUI被动接口的压力测试/性能测试
  10. 西工大第三届“探索·解密”趣味密码比赛-个人WriteUp
  11. 之前安装过Multisim14,再次安装失败的解决方法
  12. 【Hill Cipher】希尔密码描述 by Xiaosi_lemon
  13. 启动Activity时显示空白界面的问题
  14. mysql获取字符串长度函数(CHAR_LENGTH)
  15. outlook客户端 outlook.com邮箱设置方法
  16. MySQL8下载安装卸载教程
  17. Variational Inference入门:variational bayesian EM
  18. 面对来势汹汹的AI大潮,你该如何应对?
  19. 2021github仓库操作流程手册指南
  20. 电子科技大学858通信考研最新情况分析

热门文章

  1. 使用HTML5技术控制电脑或手机上的摄像头(转载)
  2. tomcat服务器开启gzip功能的方法
  3. HDU3791 二叉搜索树【二叉搜索树】
  4. NUC1840 Graveyard Design【尺取法】
  5. 51Nod-1002 数塔取数问题【DP】
  6. 代码好味道、坏味道与重构
  7. matlab 集合操作
  8. 天主教、新教、东正教
  9. Spark 机器学习 —— ALS
  10. 逻辑思维与C/C++解题