可变类与不可变类的区别

可变类与不可变类的区别

所谓不可变类:

是指当创建了这个类的实例后,就不允许修改它的属性值。在JDK的基本类库中,所有基本类型的包装类,如Integer和Long类,都是不可变类,java.lang.String也是不可变类。

不可变类:

当你获得这个类的一个实例引用时,你不可以改变这个实例的内容。不可变类的实例一但创建,其内在成员变量的值就不能被修改。

如何创建一个不可变类?

这道题90%以上的人都会被挂或者只回答一半对,来看:

1. 所有成员都是private
2. 不提供对成员的改变方法,例如:setXXXX
3. 确保所有的方法不会被重载。手段有两种:使用final Class(强不可变类),或者将所有类方法加上final(弱不可变类)。
4. 如果某一个类成员不是原始变量(primitive)或者不可变类,必须通过在成员初始化(in)或者get方法(out)时通过深度clone方法,来确保类的不可变。

四点中少一点,回答失败,来看一个例子:

public final class MyImmutableWrong {
    private final int[] myArray;  

    public MyImmutableWrong(int[] anArray) {
        this.myArray = anArray; // wrong
    }  

    public String toString() {
        StringBuffer sb = new StringBuffer("Numbers are: ");
        for (int i = 0; i < myArray.length; i++) {
            sb.append(myArray[i] + " ");
        }
        return sb.toString();
    }
}

以上不可变类书写错误,为什么?违犯了第四点

正确的写法:

public final class MyImmutableCorrect {
    private final int[] myArray;  

    public MyImmutableCorrect(int[] anArray) {
        this.myArray = anArray.clone();
    }  

    public String toString() {
        StringBuffer sb = new StringBuffer("Numbers are: ");
        for (int i = 0; i < myArray.length; i++) {
            sb.append(myArray[i] + " ");
        }
        return sb.toString();
    }
}
时间: 2024-10-09 11:48:01

可变类与不可变类的区别的相关文章

黑马程序员——19,Collections工具类,Arrays工具类,高级for循环,可变参数,静态导入

------<ahref="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------- 黑马程序员--19,Collections工具类,Arrays工具类 /* Collections是一个类,注意,这里后面带有一个s 千万不要和Collection弄混了!Collection只是接口而已. 两者要区别开来. Collect

java中String类为什么不可变?

在面试中经常遇到这样的问题:1.什么是不可变对象.不可变对象有什么好处.在什么情景下使用它,或者更具体一点,java的String类为什么要设置成不可变类型? 1.不可变对象,顾名思义就是创建后的对象不可以改变,典型的例子有java中的String类型. 2.相比于可变对象,不可变对象有很多优势: (1)不可变对象可以提高String Pool(字符串常量池)的效率和安全性.如果你知道一个对象是不可变动 ,那么需要拷贝的对象的内容时就不用复制它本身二只是复制它的地址,复制地址(通常一个指针的大小

Java String类为什么不可变?

原文地址:# Why String is immutable in Java? 众所周知,String类在Java中是不可变的.不可变类简单地说是实例不可修改的类.对于一个实例创建后,其初始化的时候所有的信息都不能被修改.不可变类有很多的好处,本文简述为什么String类要设计成不可变类.本文将从内存,同步性,数据结构的角度说明不变性的概念. 1.字符串常量池的需要 String常量池是方法区的一个特殊的储存区.当新建一个字符串的时候,如果此字符串在常量池中早已存在,会返回一个已经存在字符串的引

有类路由与无类路由的区别

最近看到RIP和OSPF方面了.这两个协议在NA里面被划分为距离矢量路由协议和链路状态路由协议.但是在NP里面划分路由又有种方法是基于有类的路由协议和无类的路由协议. RIP正是基于有类的路由协议,OSPF则是无类的路由协议. 有类的路由不会识别子网的信息,如宣告10.0.1.0/24 172.16.1.0/22 192.168.1.64/28 路由表中只会识别A类10.0.0.0/8,B类172.16.0.0/16 C类192.168.1.0/24 无类的路由协议不会根据A B C类来识别,根

python类中super()和__init__()的区别

本文和大家分享的主要是python开发中super()和__init__()的区别,希望通过本文的分享,对初学者学习这部分内容有所帮助. 1.单继承时super()和__init__()实现的功能是类似的 class Base(object): def __init__(self): print 'Base create' class childA(Base): def __init__(self): print 'creat A ', Base.__init__(self) class chi

类,抽象基类,接口类三者间的区别与联系(C++)

联系很明显,三个都是‘类’,如果读者对类的概念不清楚,可以参照wid的博文http://www.cnblogs.com/mr-wid/archive/2013/02/18/2916309.html. 下面着重解释一下区别,但此文仅是个人理解,如果觉得我说的不对的地方,还请赐教. (1)结构上的区别: 普通类:数据+方法+实现 抽象类:数据+方法(一定包含虚方法n>=1)+部分方法的实现 接口类:方法(纯虚方法) (2)概念上的区别: 普通的类和另外两个的区别很明显,普通类就是猫狗之类的,而抽象类

对【面向对象的类访问和对象访问的区别【this以及类访问】、静态成员的访问区别、类常量等、继承和重写、访问修饰限定符、冒泡排序】的总结

面向对象的总结1.首先面向对象的编程使用的都是使用对象作为处理对象而言[例如继承等情形,继承的本质来说,依旧针对的是对象]但是只有针对类的访问.静态成员以及访问修饰限定符时,针对的是类的概念 2.类内定义时,只有五种情形:类常量[const关键字定义并且使用类来调用]属性[这些属性和方法是针对该类实例的对象来调用]方法[在这种情形下使用$this进行指代作用环境(调用该方法的对象),只有继承中,子类实例的对象会向下传递到静态调用里]静态属性[用来作为实例该类的所有对象之间共享的数据.保存在类中]

python—类对象和实例对象的区别

最近在对RF的通讯层的模块进行封装,需要将之前放在类似main里面的一个方法,如下所示:这段代码是开发提供,用于接口测试,模拟底层通讯,具体的通讯是在dll内,python这边只是做了个封装让RF进行调用.这段通讯层的代码实质上做了五件事: 第一:加载dll: 第二:初始化dll内的通讯参数: 第三:与服务器进行连接,创建session 第四:把数据senbuffer通过sessionManger发送给服务器 第五:取得的数据返回recibuffer def testlogin(ip,port,

面向对象的类访问和对象访问的区别【this以及类访问】、静态成员的访问区别、类常量等、继承和重写、访问修饰限定符、冒泡排序

1.mysql封装类 在构造函数中定义初始化数据库连接的相关参数[因为实例化对象时传入的参数是该对象的唯一参数入口]但是不需要再构造函数中进行冗余定义,而是在构造函数中进行调用类中的其他方法的方式来实现构造函数的设置工作[这样的模块分离使逻辑更加简单] [重点]2.静态成员相当于每次实例化对象之间是有关系的[例如计数功能]因为每次实例化类时创建的对象占用的空间都是新创建的,这一点需要注意,所以同一个类下的对象之间的变量并没有交互的效果.[回想起当初函数中的静态局部变量的使用][延生到静态全局变量