Java 可变对象与不可变对象

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mingyundezuoan/article/details/84740315

可变对象与不可变对象


概念1

  • 不可变对象(Immutable Objects)即对象一旦被创建它的状态(对象的数据,也即对象属性值)就不能改变,任何对它的改变都应该产生一个新的对象
String str = "a" ; 
str = "b" ; 
// 两处的 str 不是同一个对象 == 判断 或输出 对象地址信息 不同
  • 可变对象(Mutable Objects):相对于不可变类,可变类创建实例后可以改变其成员变量值,开发中创建的大部分类都属于可变类
  • 不可变对象的类即为不可变类(Immutable Class)。JAVA平台类库中包含许多不可变类,如String、基本类型的包装类、BigInteger和BigDecimal等

不可变类

  • 类不可被继承:
    • 将类声明为final, 或者使用静态工厂并声明构造器为private。
    • 如果类可以被继承会破坏类的不可变性机制,只要继承类覆盖父类的方法并且继承类可以改变成员变量值,那么一旦子类以父类的形式出现时,不能保证当前类是否可变。
  • 使用private和final修饰符来修饰该类的属性
    注:如果成员属性为可变对象属性,不要使这些对象改变:
    1)不要提供更改可变对象的方法,如 set 方法
    2)不要共享对可变对象的引用,不要存储传给构造器的外部可变对象的引用。因为引用可变对象的成员变量和外部可变对象的引用指向同一块内存地址,用户可以在不可变类之外通过修改可变对象的值
    public final class MyImmutableDemo {  
        private final int[] myArray;  
        public MyImmutableDemo(int[] array) {  
            this.myArray = array.clone();   // 构造器的入参为引用数据类型时使用克隆
            // 当入参改变时不会影响构造器内部的数据
        }   
    }
  • 不要提供任何可以修改对象状态的方法(不仅仅是set方法, 还有任何其它可以改变状态的方法)
    • 类中通过 get 返回的属性是引用数据类型,也要返回克隆后的属性,防止调用方改变引用对象的数据

不可变对象

  • 优点:

    • 构造、测试和使用都很简单
    • 不可变对象是线程安全的,在线程之间可以相互共享,不需要利用特殊机制来保证同步问题,因为对象的值无法改变。可以降低并发错误的可能性,因为不需要用一些锁机制等保证内存一致性问题也减少了同步开销。
    • 不可变对象可以被重复使用,可以将它们缓存起来重复使用,就像字符串字面量和整型数字一样。可以使用静态工厂方法来提供类似于valueOf()这样的方法,它可以从缓存中返回一个已经存在的Immutable对象,而不是重新创建一个。
  • 缺点

    • 不可变对象最大的缺点就是创建对象的开销,因为每一步操作都会产生一个新的对象,制造大量垃圾,由于他们不能被重用而且对于它们的使用就是”用“然后”扔“,会创造很多的垃圾,给垃圾收集带来很大的麻烦

  1. JAVA - 可变对象与不可变对象 ↩︎

猜你喜欢

转载自blog.csdn.net/mingyundezuoan/article/details/84740315