前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何在java中创建不可变类?

如何在java中创建不可变类?

作者头像
三产
发布2021-01-12 10:14:52
1.9K0
发布2021-01-12 10:14:52
举报
文章被收录于专栏:用户6590312的专栏

原文【如何在java中创建不可变类?】地址

今天我们将学习如何在java中创建不变的类。不可变对象是在初始化之后状态不变的实例。例如,String是一个不可变类,一旦实例化,它的值不会改变。

不可改变的类对于缓存的目的是有益的,因为你不需要担心价值的变化。不可变类的其他好处是它本质上是线程安全的,所以在多线程环境的情况下,您不需要担心线程安全。

在这里,我提供了一种通过一个例子来创建Java中不可变类的方法,以便更好地理解。

要在java中创建不可变类,您必须执行以下步骤。

  1. 将类声明为final,因此无法扩展。
  2. 使所有字段都是私有的,以便不允许直接访问。
  3. 不要为变量提供setter方法
  4. 使所有可变字段都是最终的,以便它的值只能被分配一次。
  5. 通过执行深层拷贝的构造函数初始化所有字段。
  6. 在getter方法中执行对象的克隆以返回一个副本而不是返回实际的对象引用。

要了解第4点和第5点,我们来运行Final类,其效果很好,实例化后值不会被更改。

FinalClassExample.java

代码语言:javascript
复制
import java.util.HashMap;
import java.util.Iterator;

/**
 * <p></p>
 *
 * @author 三产
 * @version 1.0
 * @date 2017-03-24
 * @QQGroup 213732117
 * @website http://www.coderknock.com
 * @copyright Copyright 2017 拿客 coderknock.com  All rights reserved.
 * @since JDK 1.8
 */
public class FinalClassExample {

    private final int id;

    private final String name;

    private final HashMap<String,String> testMap;

    public int getId() {
        return id;
    }


    public String getName() {
        return name;
    }

    /**
     * 可变对象的访问器函数
     */
    public HashMap<String, String> getTestMap() {
        return (HashMap<String, String>) testMap.clone();
    }

    /**
     * 构造函数 执行深层复制
     * @param i
     * @param n
     * @param hm
     */

    public FinalClassExample(int i, String n, HashMap<String,String> hm){
        System.out.println("执行 深复制 对象初始化");
        this.id=i;
        this.name=n;
        HashMap<String,String> tempMap=new HashMap<String,String>();
        String key;
        Iterator<String> it = hm.keySet().iterator();
        while(it.hasNext()){
            key=it.next();
            tempMap.put(key, hm.get(key));
        }
        this.testMap=tempMap;
    }

    /**
     * 测试 浅复制 的后果以及如何避免使用 深复制 创建不可变类
     * @param args
     */
    public static void main(String[] args) {
        HashMap<String, String> h1 = new HashMap<String,String>();
        h1.put("1", "first");
        h1.put("2", "second");

        String s = "original";

        int i=10;

        FinalClassExample ce = new FinalClassExample(i,s,h1);

        //让我们看看它是按字段还是引用复制。
        System.out.println(s==ce.getName());
        System.out.println(h1 == ce.getTestMap());
        //print the ce values
        System.out.println("ce id:"+ce.getId());
        System.out.println("ce name:"+ce.getName());
        System.out.println("ce testMap:"+ce.getTestMap());
        //修改本地变量的值
        i=20;
        s="modified";
        h1.put("3", "third");

        System.out.println("ce id after local variable change:"+ce.getId());
        System.out.println("ce name after local variable change:"+ce.getName());
        System.out.println("ce testMap after local variable change:"+ce.getTestMap());

        HashMap<String, String> hmTest = ce.getTestMap();
        hmTest.put("4", "new");

        System.out.println("ce testMap after changing variable from accessor methods:"+ce.getTestMap());

    }
}

输出如下:

代码语言:javascript
复制
执行 深复制 对象初始化
true
false
ce id:10
ce name:original
ce testMap:{1=first, 2=second}
ce id after local variable change:10
ce name after local variable change:original
ce testMap after local variable change:{1=first, 2=second}
ce testMap after changing variable from accessor methods:{1=first, 2=second}

修改构造函数为浅复制,输出如下:

代码语言:javascript
复制
执行 浅复制 对象初始化
true
false
ce id:10
ce name:original
ce testMap:{1=first, 2=second}
ce id after local variable change:10
ce name after local variable change:original
ce testMap after local variable change:{1=first, 2=second, 3=third}
ce testMap after changing variable from accessor methods:{1=first, 2=second, 3=third}

对比两次输出可以看出,HashMap 值由于构造函数中的浅复制而改变,并提供对getter函数中原始对象的直接引用。

进一步阅读:如果不可变类有很多属性,其中一些属性是可选的,我们可以使用构建器模式创建不可变类

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017/03/24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档