java中一个类是不可变类的条件是啥?求详细解答。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java中一个类是不可变类的条件是啥?求详细解答。相关的知识,希望对你有一定的参考价值。

疑问:书上说:“一个类所有数据都是私有的而且没有修改器,并不意味他一定是不可变类。”这个似乎与不可变类的判断条件矛盾,我该怎么理解?到底怎样判断一个类是不是不可变类?

不可变类的唯一判断条件是:
“ 不可变类的实例在实例的整个生命周期中永远保持初始化的状态”

比如一个类里面有个属性是private List list,然后只提供了getList()方法,但是你还是可以通过getList().add(XXX)来修改list的内容。即是,它没有保持“初始化”状态,它是个可变类。

来自百度:

可变类和不可变类(Mutable and Immutable Objects)的初步定义:
可变类:当你获得这个类的一个实例引用时,你可以改变这个实例的内容。
不可变类:当你获得这个类的一个实例引用时,你不可以改变这个实例的内容。不可变类的实例一但创建,其内在成员变量的值就不能被修改。
如何创建一个自己的不可变类:
.所有成员都是private
.不提供对成员的改变方法,例如:setXXXX
.确保所有的方法不会被重载。手段有两种:使用final Class(强不可变类),或者将所有类方法加上final(弱不可变类)。
.如果某一个类成员不是原始变量(primitive)或者不可变类,必须通过在成员初始化(in)或者get方法(out)时通过深度clone方法,来确保类的不可变。
参考技术A "一个类所有数据都是私有的而且没有修改器,并不意味他一定是不可变类",意思就是这个类的私有数据是可以通过某种方式改变,比如内部类改变等
不可变类的条件 :这个类的所有数据都加了 final 关键字 那么这个类new 出来的对象是数据是不可改变的。
参考技术B 所谓不可变类,是指当创建了这个类的实例后,就不允许修改它的属性值 参考技术C 学习下

Java中String为什么是不可变的

1、在Java中,String类是不可变类,一个不可变类是一个简单的类,并且这个的实例也不能被修改,

这个类的实例创建的时候初始化所有的信息,并且这些信息不能够被修改

2、字符串常量池

字符串常量池是方法区中一块特殊的存储区域,当创建一个字符串常量的时候,判断该字符串字在符串字符串常量池中是否已经存在

如果存在,返回已经存在的字符串的引用;如果不存在,则创建一个新的字符串常量,并返回其引用

String string1 = "abcd";
String string2 = "abcd";

变量string1,string2指向常量池中的同一个字符串常量对象;如果String是可变的,给一个变量重新赋值一个引用,将会指向错误的值

3、缓存哈希值

在Java中字符串的哈希值会经常被使用到。例如在HashMap中,String的不可变总能保证哈希值总是相等的,并且缓存起来,不用担心会改变,

那意味着不需要每次都计算哈希值,这样会提高效率。在String类中有以下的代码:

private int hash; //用来缓存哈希值

3、促进其他对象的使用

HashSet<String> set = new HashSet<String>();
set.add(new String("a"));
set.add(new String("b"));
set.add(new String("c"));

for(String a: set)
a.value = "a";

在上述代码中,如果String是可变的,那么它的值会被改变,但是这违背了Set集合元素不能重复的设计

4、安全性

String被作为参数广泛的在 Java 类中、网络连接中、和文件操作中使用,如果字符串可变,那么在这些模块中,将会引发严重的安全性问题

boolean connect(string s){
  if (!isSecure(s)) { 
    throw new SecurityException(); 
  }
  //here will cause problem, if s is changed before this by using other references. 
  causeProblem(s);
}

5、不可变的对象同样是线程安全的

因为不可变的对象不能被改变,他们可以在多个线程中共享,就不需要使用线程的同步操作

总之,把String设计为不可变,是为了提高效率和安全性。在广泛的设计开发中,不可变类是首要选择。

 

以上是关于java中一个类是不可变类的条件是啥?求详细解答。的主要内容,如果未能解决你的问题,请参考以下文章

java中的增强for循环,是啥?语法结构和使用得条件?详细解答就加高分。

C#中string类型是啥类型

关于Java中的String类的不可变

有关 java 重写equals 方法, 判断两个点是不是相同,求高手详细解答,谢谢!!!!!

c语言中,为啥在64位系统中long跟指针的大小是8,而32位的却是4?是啥导致不一样?求详细解答

java中找不到主类是啥问题