首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何创建对不可变类的可重新赋值引用?

对于不可变类,通常是指类的实例在创建后不可被修改。这意味着类的属性值在对象创建后不能被更改。然而,有时候我们可能需要在不违反不可变性的前提下,重新赋值一个新的引用。

在Java中,可以通过使用final关键字来创建不可变类。final关键字可以应用于类、方法和变量。对于类来说,使用final关键字修饰的类不能被继承。对于方法来说,使用final关键字修饰的方法不能被子类重写。对于变量来说,使用final关键字修饰的变量只能被赋值一次,之后不能再修改。

要创建对不可变类的可重新赋值引用,可以使用一个可变的包装类来包装不可变类的实例。例如,可以使用AtomicReference类来包装不可变类的实例,从而实现可重新赋值引用的效果。

下面是一个示例代码:

代码语言:java
复制
import java.util.concurrent.atomic.AtomicReference;

public class ImmutableClassExample {
    private final String value;

    public ImmutableClassExample(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public static void main(String[] args) {
        ImmutableClassExample immutableObj = new ImmutableClassExample("Initial value");
        AtomicReference<ImmutableClassExample> reference = new AtomicReference<>(immutableObj);

        // 修改引用指向的对象
        ImmutableClassExample newImmutableObj = new ImmutableClassExample("New value");
        reference.set(newImmutableObj);

        System.out.println(reference.get().getValue());  // 输出: New value
    }
}

在上面的示例中,我们创建了一个不可变类ImmutableClassExample,它有一个value属性和一个getValue()方法。然后,我们使用AtomicReference类来包装该不可变类的实例,并通过reference.set()方法重新赋值引用。最后,我们通过reference.get().getValue()方法获取新的引用指向的对象的值。

需要注意的是,虽然我们可以重新赋值引用,但不可变类的属性值仍然是不可修改的。这样做的好处是可以在不违反不可变性的前提下,实现引用的重新赋值。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Java Review (十二、面向对象----final 修饰符)

初始化时,系统会为该类变量分配内存,并分配默认值 ; 当创建对象时,系统会为该对象实例变量分配内存,并分配默认值。...修饰基本类型变量和引用类型变量区别 当使用 final 修饰基本类型变量时,不能对基本类型变量重新赋值,因此基本类型变量不能被改变 。...public final class Test { // 体 } 不可变可变( immutable ) 意思是创建该类实例后,该实例 实例变量是不可改变。...Java 提供 8 个包装和 java.lang.String 都是不可变 , 当创建它们实例后 , 其实例实例变量不可改变。...Double d = new Double(6.5) ; String str =new String( "Hello"); 如果需要创建自定义可变遵守如下规则 。

45740

python高级编程第三讲:set、dict深入和垃圾回收

keys values items deepcopy 深拷贝 ,深拷贝后字典进行操作不会影响原字典 深拷贝要先引入一个 import copy a = {"key":{"addr“:"bjc...b'}) 2 迭代形式为 [('a','b')] 列表包括元组形式 3 a.update(name='zc',age=19) 字典取值说明 建议用 a['value'] 这种直接取,如果此时取一个不存在...,可变性和垃圾回收 1 ==和is区别 is是判断两个对象id值是否相等 == 是判断值是否相等 但是以上中有一个int类型是特殊,因为有小整数对象池和大整数对象池,程序自动在创建相应对象池...2 del语句和垃圾回收(GC) 其实垃圾回收就是统计对象引用计数,当计数为0时候,该对象就会被释放回收,但是循环引用时候 参考资料: https://blog.csdn.net/qq_37616069...以int类型为例:实际上 i += 1 并不是真的在原有的int对象上+1,而是重新创建一个value为6 int对象,i引用自这个新对象。

52010
  • String、StringBuilder、StringBuffer区别;String底层详解,实例化、拼接、比较;String为什么不可变

    【new相当于在堆中新建了value值,每new一个对象就会在堆中新建,地址值也因此不同,堆中value存储着指向常量池引用地址】由于new关键字会在堆中开辟空间,因此开发中一般建议使用,直接用字面量形式赋值即可...将变量重新赋值创建了一个新对象、然后将新对象引用赋值给了变量,之前对象是没有受到影响 public static void main(String[] args) { String str1...= "abc"; str1 = "xyz"; System.out.println(str1); //xyz}再次给s赋值时,并不是原来堆中实例对象进行重新赋值,而是生成一个新实例对象...,或者在提供访问方法时,返回字段拷贝而不是直接返回字段本身对于基本类型来说,不可变 指 变量当中数据不可改变;对于引用类型来说,不可变 指 对象本身属性或数据不会改变,即一个对象重新创建后,不能对该对象进行任何更改...将变量重新赋值创建了一个新对象、然后将新对象引用赋值给了变量,之前对象是没有受到影响。3)引用可变可变类型值已经不可再改变,但可以修改指向。

    22210

    Java关键字final、static总结与对比

    原生数据类型和引用数据类型 如果被final修饰是基本数据类型变量,则其数值一旦在初始化之后便不能更改;如果是引用类型变量,一旦初始化赋值之后指向对象不可变但该对象内容可变。...new AA(); //编译失败,被final修饰引用变量一旦初始化赋值之后指向对象不可变 System.out.println( ++a.i ); //输出值为2,说明内容可变...或者用来形成静态代码块以优化程序性能 当定义一个static变量时候JVM会将其分配在内存堆上,所有程序引用都会指向这一个地址而不会重新分配内存 当修饰一个方法时候可以直接通过来调用而不需要创建对象...没有这个引用,就意味着静态内部类: 1、它创建是不需要依赖外围创建。 2、它不能使用任何外围非static成员变量和方法。...修饰:依旧是取二者共同体,所以只能修饰成员变量、方法、内部类,被static final修饰意义分别如下: 1、成员变量:属于变量且只能赋值一次,并且可以通过名访问。

    85220

    C++11第三弹:lambda表达式 | 新功能 | 模板可变参数

    ,人们开始觉得上面的写法太复杂了,每次为了实现一个algorithm算法,都要重新去写一个,如果每次比较逻辑不一样,还要去实现多个,特别是相同类命名,这些都给编程者带来了极大不便。...用追踪返回类型形式声明函数返回值类型,没有返回值时此部分省略。返回值类型明确情况下,也省略,由编译器返回类型进行推导。 {statement}:函数体。...lambda表达式之间不能相互赋值,即使看起来类型相同 新功能 默认成员函数 原来C++中,有6个默认成员函数: 构造函数 析构函数 拷贝构造函数(深拷贝) 拷贝赋值重载(深拷贝) 取地址重载 const...默认成员函数就是我们写编译器会生成一个默认。C++11 新增了两个:移动构造函数(移动拷贝)和移动赋值运算符重载(移动拷贝)。...在C++标准库中,流对象希望被拷贝: 继承和多态中final与override关键字 模板可变参数 C语言中可变参数 C语言中也有可变参数概念,他底层是一个动态数组,存一个可变参数,

    8710

    Android | 如何使程序实现线程安全(拓展关键词:ThreadLocal、重排序、volatilefinal)

    是否知道final、volatile关键字作用(中级) 是否清楚1.5之前Java DCL 为什么有缺陷(中级) 是否清楚地知道如何编写线程安全程序(高级) 是否ThreadLocal使用注意事项有认识...可能共享CPU时间片; 线程是存在于进程当中, 同一个进程中线程之间是可以共享内存; 线程安全产生原因:可变资源(内存)线程间共享(关键词“可变”和“共享”) 线程间共享资源不用考虑线程安全了...共享资源 共享才会产生线程安全问题, 所以尽量共享; 共享不可变资源(volatile、final) 禁止重排序 有条件地共享可变资源 (更改刷新)可见性 一个线程共享资源修改...操作原子性 禁止重排序 共享资源 重入函数: 传入一个参数进函数,经过一系列运算, 再把运算结果返回出去, 中间不会涉及到任何对外部内存访问、修改, 没有副作用, 像这样没有副作用函数...重排序分为三: 编译器重排序:不改变单线程程序语义前提下,重新安排执行顺序 指令级并行重排序: 指令并行技术可以将多条指令重叠执行, 如果不存在数据依赖性, 处理器会改变语句对应机器指令执行顺序

    1.1K10

    Java 中变量与数据类型

    声明一个变量类型后,不能用它来存储其类型数据。 变量定义时可以赋初始值,但是在使用时必须赋值。 变量是有使用范围,在同一使用范围内,不能重复定义同一个变量。...变量最重要一个特点就是可以重新赋值。...在 Java 中,基本数据类型属于 Java 一种内置特殊数据类型,不属于任何,所以可以直接其进行赋值;给基本类型变量赋值方式就叫做 字面值; float score = 89.0f; int...age = 26; 引用数据类型 常见引用数据类型 数据类型 默认值 数组 null null 接口 null 而对于引用数据类型,我们经常是需要 new 关键字来进行赋值,但是引用类型中...对象已经被创建过,那么就会优先从字符串常量池中获取其引用,其不可变性确保了不同引用指向同一 String 对象; 安全性 我们经常用 String 作为我们方法参数,其不变性能够保证参数不可变; 线程安全

    53630

    Python常见编程基础问题总结

    Python global 语句作用 在编写程序时候,如果想要**改变(重新赋值)**函数外部变量,并且这个变量会作用于许多函数中,就需要告诉 Python 程序这个变量作用域是全局变量,global...__init__ 方法并不是真正意义上构造函数, __new__ 方法才是(构造函数是一种特殊成员函数,它会在每次创建新对象时执行); __new__ 方法用于创建对象并返回对象,当返回对象时会自动调用...(变量进行重新赋值除外 rebind the reference in the method) 将不可变对象:字符串string、元组tuple、数值numbers,作为参数传递给函数,函数内部将其改变后...静态语言在定义变量时必须指定变量类型,如果赋值时候类型匹配,就会报错,Java/C++ 都是静态语言(int a; a = 100) Python 装饰器理解 装饰器本质上是一个 Python 函数或...当浅复制值是不可变对象(数值,字符串,元组)时和=“赋值情况一样,对象 id 值与浅复制原来值相同。 2、复制可变数据类型: 直接赋值:其实就是对象引用(别名)。

    1K20

    灵魂拷问:为什么 Java 字符串是不可变

    借此机会,我就和大家一起,“为什么 Java 字符串是不可变”进行一次深入地研究。注意了,准备打怪升级了! 01、图文分析 来看下面这行代码。...String alita = "阿丽塔"; 这行代码在字符串常量池中创建了一个内容为“阿丽塔”对象,并将其赋值给了字符串变量 alita(存储是字符串对象"阿丽塔"引用)。如下图所示。 ?...alita = "战斗天使".concat(alita); 这行代码将字符串“战斗天使”拼接在字符串变量 alita 前面,并重新赋值给 alita。这个过程就比之前复杂了。...concat(),看似都能改变字符串内容,但其实都是在方法内部使用 new 关键字重新创建新字符串对象。...如果需要一个修改字符序列,建议使用 StringBuffer 或 StringBuilder 代替 String ,否则每次创建字新符串对象会导致 Java 虚拟机花费大量时间进行垃圾回收。

    63220

    【剑指 Java】第 1 弹:靠这份 Java 基础知识总结,我拿到了满意 Offer

    ) int y = x; 基本类型与对应封装不同 基本类型只能按值传递,封装引用传递; 基本类型 会在 栈 中创建,效率较高,但可能存在内存泄露问题;封装对象会在堆中创建,其 引用在栈中创建...如果一个 String 对象已经被创建过,那么就会优先从字符串常量池中获取其引用,其不可变性确保了不同引用指向同一 String 对象; 安全性 我们经常用 String 作为我们方法参数,其不变性能够保证参数不可变...即 值传递是实参一个副本,副本操作不会影响实参原始值,也即无论形参如何变化,都不会影响到实参内容。...(如重新赋值引用),则形参操作,不会影响实参指向对象内容。...具有如下特点: 对象类型不可变,但引用类型可变; 对象类型和引用类型之间有继承()/实现(接口)关系; 方法具有多态性,但属性不具有; 若子类重写了父方法,则真正执行是子类覆盖方法,若子类未覆盖父方法

    49020

    一起长锈:4 默认不可变变量绑定与引用(从Java与C++转Rust之旅)

    ,在掌握了Rust编程知识之后,为了通过Rust项目组技术面试,使得转岗成功而至被裁员,她必须领会编程如何"快速"才能有真正意义。...“赋值语句在 Rust 中用来修改已经绑定变量值。如果变量是可变,也就是用 mut 声明,那就可以对其进行重新赋值。” “比如在我们代码中这两行。上面一行就是变量绑定,非常简洁。...赵菲:“嘿,为啥Rust要设计变量绑定这样机制呢?有啥好处?” 贾克强:“Rust变量绑定跟Java或C++赋值不一样,其实主要是体现了更深语言设计原则和变量行为差别。”...4.2 默认不可变引用菲:“你能给我浅浅地解释一下Rust引用吗?” 贾克强:“当然可以。Rust中引用,就是一种借用数据方式,分为不可变引用(&T)和可变引用(&mut T)。...如果使用mut声明,可以重新赋值 默认情况下,变量赋值可变赋值涉及所有权或范围概念。值被复制到预分配内存中 默认情况下,变量赋值可变。需要使用new和delete进行显式内存管理。

    22943

    灵魂拷问:为什么 Java 字符串是不可变

    借此机会,我就和大家一起,“为什么 Java 字符串是不可变”进行一次深入地研究。注意了,准备打怪升级了! 01. 图文分析 来看下面这行代码。...String alita = "阿丽塔"; 这行代码在字符串常量池中创建了一个内容为“阿丽塔”对象,并将其赋值给了字符串变量 alita(存储是字符串对象"阿丽塔"引用)。如下图所示。 ?...alita = "战斗天使".concat(alita); 这行代码将字符串“战斗天使”拼接在字符串变量 alita 前面,并重新赋值给 alita。这个过程就比之前复杂了。...concat(),看似都能改变字符串内容,但其实都是在方法内部使用 new 关键字重新创建新字符串对象。...如果需要一个修改字符序列,建议使用 StringBuffer 或 StringBuilder 代替 String ,否则每次创建字新符串对象会导致 Java 虚拟机花费大量时间进行垃圾回收。

    43510

    2018年8月26日python内存分析

    ***************** PYTHON 中根据数据是否可以进行修改提供了两种不同数据类型: 不可变数据类型:一般基本数据类型都是不可变数据类型 可变数据类型:一般组合数据类型或者自定义数据都是可变数据类型...可变数据类型特点:(组合数据类型特点) 创建对象内部数据可以改变,但是指向内存地址不会改变(1变是内部数据可以改变) 创建相同数据可变数据类型对象,指向地址是不一样,因为创建每一个可变数据类型对象...不可变数据类型是在定义了数据之后,修改变量数据,变量不会修改原来内存地址数据 而是会指向新地址,原有的数据保留,这样更加方便程序中基本数据利用率 python基本数据类型进行了基本优化操作...一共有三种解决方式: 1.对象引用赋值 2.对象浅拷贝 3.对象深拷贝 1.首先对象引用赋值是指:(只适用于可变数据类型) 将对象内存地址同时赋值给多个变量,多个变量指向是同一个内存地址...义 class 类型,都具备引用赋值操作;但是不适合不可变类型,不可变类型引用赋值 操作有只读特征,一旦通过变量重新赋值就会重新指向新引用对象 自定义数据类型:就是自己写 ?

    93140

    C++11『右值引用 ‖ 完美转发 ‖ 新增功能 ‖ 可变参数模板』

    现有对象 临时对象或可移动对象 典型用途 函数参数、返回类型 移动语义、完美转发 示例 int x = 10; int& ref = x; int&& rref = 10; 重新赋值 是 是 可为...简单来说就是 右值属性转早了 解决问题核心在于 perfectForward 传递 val 参数时,如何保证它 右值属性 丢失 2.2.传参过程中保持右值属性 要想在参数传递过程中保持其 右值属性..., 拷贝构造 和 赋值重载 进行了 “升级”,增加了 移动构造 和 移动赋值 这两个新函数,至此,中共有八个天选之子(编译器会默认生成) 天选之子 意思就是 即使我们写,编译器也会默认生成(有条件...如果我们实现了 析构、拷贝构造、赋值重载,就证明当前中涉及到了 动态内存管理,是需要自己进行 深拷贝 ,编译器无能为力,移动语义 也应该根据自己实际场景进行设计,所以编译器就没有自动生成 如何自己实现这两个...比如在 单例模式 中,只允许创建一个对象,为了避免外部再次创建对象,需要将 构造、拷贝构造、移动构造 等函数删除;再比如 C++ 中 IO 流中,是不允许 IO 对象之间进行拷贝,因为每个 IO

    48250

    Python变量类型及变量引用

    二、变量类型        Python 包含像 int 这样简单类型 —— 只有对象类型, 如果 Python 中需要整数值,将整数赋值给相应变量(如i = 100 )即可。...在后台,Python 将创建一个整数对象,并将对新对象引用赋值给变量。         问题关键是:Python 是一种动态类型化语言,所以无需声明变量类型。...此外,对象还分两:一修改,一是不可修改。...因为对象不可变。那什么可变?变量引用可变! 好,那么自然剩下就是可变对象了,上面的实验亦可以很容易证实字典、列表、集合和实例等对象是可变。那么,这意味着什么呢?...因此我们发现,他和参数一样,传值传引用表面上看过去漂移不定。那么如何修改一个指向不可变全局变量值呢?靠返回值显然不那么优美。

    2.5K30

    Java面试题(二):你真的懂这几道题了吗?

    问题来源:史上最全各类面试题汇总,没有之一,不接受反驳 1、能否创建一个包含可变对象可变对象? 虽然很多人听说过不可变对象,但你不一定懂,以及知道怎么创建。...不可变对象:不可变对象(Immutable Objects)即对象一旦被创建状态(对象数据,也即对象属性值)就不能改变,任何改变都应该产生一个新对象 如何创建可变?...多态一些优点总结: 替换性:多态已存在代码具有替换性 可扩充性:增加新子类不影响已经存在结构 接口性:多态是超通过方法签名,向子类提供一个公共接口,由子类来完善或者重写它来实现。...注意,被 final 修饰变量,只是值这个变量不能在被赋值了,变量所指向对象还是可以改变。...,只是这个变量本身不能在被赋值,所以我们也经常把被 final 修饰变量称之为常量。

    43920

    python数据类型简介

    'jerry',但是当我们name重新赋值时候,并不是改变jerry这个值,而是新建一个值'tom',再把name重新指向到tom,所以两次nameid不一样,'jerry'和'tom'这种值在python...中不叫值,而是被认为是一个对象 python核心概念就是'一切皆对象',根据值可变与否可以分为可变和不可变对象,我个人是这么理解: "可变对象都是可变对象引用集合,改变可变对象时候...l1数据对象部分,当l1重新赋值时候,并不影响l2值 l1、l3和l2[0],引用都是同一数据对象,所以id都相同 从上面就不难理解:'python变量没有类型,数据才有类型'这句话...,它类似于一种框架,当我们需要用到它时候就它进行实例化,比如: name='jerry',name可以看做字符类型str()一个实例 属性:数据,可以用" 实例.属性名 "引用 方法:...操作,可以用" 实例.方法名()"引用 属性与方法区别在于,属性引用是数据,而方法引用是一段代码,属性是在实例化过程中进行赋值,而方法则定义时就已经写好,所以,当某个变量属于某个时,

    79920

    聊一聊Java字符串可变

    再通过上述代码,我们将变量 a 赋值给变量 b ,变量 b 也存储了字符串对象 string引用,它们指向是同一个对象。 ? 当我们尝试变量 a 重新赋值,看下变量 b 会不会有影响呢 ?...将变量 a 重新赋值后,保存了新引用,而不是直接在原有的字符串对象上进行数据改变,同时变量 b 仍然存是对象 string 引用,变量 a 和 b 两者相互独立,不影响,这也正是说明了 String...在这里初认 Java 小伙伴还可能会有些困惑:一个String对象 a 赋值 string,然后又让 a 值为 string2,这个时候a值变成 了string2, a 值改变了,为什么还说 String...其实问题也很简单,这里 a 只是存储 String 对象引用,并不是对象本身,a 存储是指向对象所在内存地址引用罢了,当第二次赋值时,a 引用指向了对象 string2内存地址,而对象 string2...是重新创建,之前 string 对象仍在内存中,并且由变量 b 引用着。

    76830

    第5章 | 共享与可变,应对复杂关系

    5.4 共享与可变 迄今为止,本书讨论都是 Rust 如何确保不会有任何引用指向超出作用域变量。但是还有其他方法可能引入悬空指针。下面是一个简单例子: let v = vec!...在可变引用整个生命周期中,无论是它引用目标,还是该引用目标间接访问任何目标,都没有任何其他路径访问。可变引用来说,唯一能和自己生命周期重叠引用就是从可变引用本身借出引用。...每种引用都会影响到我们可以对“到引用目标从属路径上值”以及“从引用目标间接访问值”所能执行操作,如图 5-9 所示。...Rust 中到处都在应用这些规则:如果要借用 HashMap 中键共享引用,那么在共享引用生命周期结束之前就不能再借入 HashMap 可变引用。...在 Rust 中创建循环引用(两个值,每个值都包含指向另一个值引用)相当困难。你必须使用智能指针类型(如 Rc)和内部可变性(目前为止本书还未涉及这个主题)。

    10210
    领券