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

创建一个`Copyable`类型的接口而不是使用`Cloneable`有意义吗?

创建一个Copyable类型的接口而不是使用Java中的Cloneable接口确实是有意义的,尤其是在需要更灵活和安全的对象复制机制时。以下是关于这种做法的基础概念、优势、类型、应用场景以及可能遇到的问题和解决方案的详细解释。

基础概念

Cloneable接口

  • Java中的Cloneable接口是一个标记接口,用于指示一个类的实例可以被克隆。
  • 实现Cloneable接口的类必须重写Object类的clone()方法,并且该方法需要处理CloneNotSupportedException异常。

Copyable接口

  • Copyable接口是一个自定义接口,可以定义自己的复制逻辑。
  • 这个接口可以提供更灵活的复制机制,比如深拷贝和浅拷贝的选择。

优势

  1. 灵活性
    • 自定义的Copyable接口允许开发者根据具体需求实现不同的复制策略。
    • 可以轻松地在深拷贝和浅拷贝之间切换。
  • 安全性
    • 避免了Cloneable接口可能带来的安全问题,比如对象状态的不一致。
    • 可以更好地控制复制过程中的数据访问权限。
  • 可读性和维护性
    • 自定义接口使得代码意图更加明确,易于理解和维护。
    • 可以通过命名约定来清晰地表达复制行为的意图。

类型

  1. 浅拷贝(Shallow Copy)
    • 只复制对象本身及其基本类型的字段,引用类型的字段仍然指向同一个对象。
  • 深拷贝(Deep Copy)
    • 复制对象及其所有嵌套的对象,确保所有层次的对象都是独立的副本。

应用场景

  • 复杂对象图:当对象包含多个嵌套对象时,深拷贝可以确保整个对象图的独立性。
  • 并发编程:在多线程环境中,深拷贝可以避免共享对象带来的同步问题。
  • 持久化存储:在将对象保存到数据库或文件系统之前,深拷贝可以确保原始对象不受影响。

示例代码

以下是一个简单的Copyable接口及其实现示例:

代码语言:txt
复制
public interface Copyable<T> {
    T copy();
}

public class Person implements Copyable<Person> {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public Person copy() {
        return new Person(this.name, this.age);
    }

    // Getters and setters
}

可能遇到的问题和解决方案

问题1:如何实现深拷贝?

解决方案: 可以使用序列化(Serialization)来实现深拷贝。将对象序列化为字节流,然后再反序列化回来,这样可以创建一个完全独立的副本。

代码语言:txt
复制
import java.io.*;

public class DeepCopyUtil {
    @SuppressWarnings("unchecked")
    public static <T extends Serializable> T deepCopy(T obj) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(obj);
            oos.close();

            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            T copy = (T) ois.readObject();
            ois.close();

            return copy;
        } catch (IOException | ClassNotFoundException e) {
            throw new RuntimeException("Deep copy failed", e);
        }
    }
}

问题2:如何处理循环引用?

解决方案: 在实现深拷贝时,需要注意处理循环引用的情况。可以使用一个缓存机制来存储已经复制过的对象,避免无限递归。

代码语言:txt
复制
import java.io.*;
import java.util.*;

public class DeepCopyUtil {
    private static final Map<Object, Object> copiedObjects = new IdentityHashMap<>();

    @SuppressWarnings("unchecked")
    public static <T extends Serializable> T deepCopy(T obj) {
        if (copiedObjects.containsKey(obj)) {
            return (T) copiedObjects.get(obj);
        }

        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(obj);
            oos.close();

            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            T copy = (T) ois.readObject();
            ois.close();

            copiedObjects.put(obj, copy);
            return copy;
        } catch (IOException | ClassNotFoundException e) {
            throw new RuntimeException("Deep copy failed", e);
        }
    }
}

通过这种方式,可以创建一个更加灵活和安全的对象复制机制,满足不同的应用需求。

相关搜索:在这种情况下,使用一个表而不是多个表有意义吗?希望创建一个动态修饰符,而不是返回必要的类型使用Ninject,我可以从接口创建一个实例而不暴露我的具体类吗?在向量中插入时,使用lambda的返回值而不是函数的返回值有意义吗?如何打开一个而不是所有使用.map()创建的div创建一个接口类的实例而不是仅仅将该接口添加到主类中进行回调有什么好处?使用MySQL而不是SQLite创建一个新的Ruby on Rails应用程序我应该在创建Xamarin对象的类的签名中使用BindingBase而不是Binding吗?在C#中使用接口而不是继承时覆盖另一个类的虚方法?使用Files.move创建新的“文件”文件类型,而不是将文件移动到目录中当我从一个扩展了特定接口的类创建一个对象时,我可以在使用这个接口的地方使用这个对象吗?我可以在Kotlin中创建一个完全空的LongArray,而不是用0(零)填充吗?在React Native中使用数组映射而不是FlatList是一个好的模式吗?如何在我的类中使用命令而不是事件来创建一个名为TapGestureRecognizer的方法?在lightning web组件上创建一个任务,而不是只使用顶尖的javascript控制器?有没有可能创建一个带有属性类型的接口,该属性类型会根据另一个属性而改变,而不需要在编译时显式地知道它?如果我们只有一个有状态pod的副本,我们可以使用部署资源而不是StatefulSet吗?Laravel -在路由中使用(一个get和一个post)而不是(资源,只使用索引和存储)是标准的吗?将CSS选择器放在类型的第一个而不是第一个子项一起使用如何使用json模块将python对象转换为(json)嵌套的dict,而不是创建一个类似文件的对象?
相关搜索:
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

白话设计模式之原型模式

然后再创建出一个同拷贝对象一样的对象(但是它们并不是同一个对象,只是类型相同罢了),只不过他不是通过对象的构造函数进行赋值而来的,而是基于内存的二进制流进行复制,所以效率比new一个对象进行复制要高效。...Java为我们内置了原型接口(Cloneable),如果要进行对象的拷贝,必须实现Cloneable接口,它是一个空接口,里面没有任何的方法,它只是一个规约而已,我们实现Cloneable接口只需要在类里面重写...一.首先定义一个原型类;让其实现Cloneable接口,并重写Object clone()方法 我们从clone()方法中看出它使用了super.clone()进行拷贝,super.clone()是直接使用内存的二进制流进行复制...发现,原女友没有按摩洗脚的任务了,小命终于保住了,使用了深克隆后,我们发现她们两个的任务不再一样了,为什么之前使用浅克隆是一样的呢,因为她们的任务是一个引用类型,使用浅克隆时复制的其实不是它们的值,而是它们的地址...,是的,少的话可能体现不出来,但是如果这个类的属性特别多,又特别复杂的时候,你还会选择一个一个的取set吗?

24510
  • C.43:保证(值类型)可拷贝类有默认构造函数

    默认值的缺失可能令用户感到意外并且增大使用的难度,因此如果有可能合理地定义它,就那样做。...{0,0,0}在大多数日历系统中都不是合法的日期,因此选择它将会引起类似浮点数的NaN问题。 NaN:不是数字,或者说无效数字。...这样的类型可以自然地使用特殊状态作为默认构造的初始值,不管它是否是可拷贝的。...类似的可拷贝的特殊状态类型,例如包含“==nullptr"这样的特殊状态的可拷贝的智能指针,应该使用特殊状态作为它们默认构造的初始值。...然而,更可取的做法是让默认构造函数默认生成一个有意义的状态,例如std::string的“”和std::vectors{}。

    50210

    Swift 周报 第三十二期

    提案 本期提案没有最新内容,期待下期更新~~ Swift论坛 提议使用部分不可复制类型的字段[2] 介绍 当前给定一个类似于 var 的构造(例如:var、inout),Swift 不允许部使用耗该类型的存储字段...具有 Deinits 的类型的部分消耗 禁止使用 deinits 部分消耗不可复制类型,因为当字段被部分消耗,允许该类型被销毁 例如: struct E : ~Copyable struct S : ~...第一个是使索引类型也持有对该对象的强引用。但是担心当用户没有意识到他们通过索引持有强大的参考时,可能会产生问题。 第二个是使元素类型为T?而不是 T。...回答: 不是集合似乎是所提供的数据结构的固有属性,而不是实现限制。如果序列中的第 n 个项目可以从 x 更改为 y,因为 x(或序列中较早的某个其他对象)已被收集,则序列没有稳定的索引。...为什么在宏中需要 UIKit(而不是在声明宏的包中)?

    29830

    Java的对象克隆

    本节我们会讨论 Cloneable 接口,这个接口指示一个类提供了一个安全的 clone() 方法。...(出于这个原因,这个例子使用 Date 类型的域而不是 LocalDate 来展示克隆过程。如果 hireDay 是不可变的 LocalDate 类的一个实例,就无需我们做任何处理了。)...Cloneable 接口Cloneable 接口的出现与接口的正常使用并没有关系。具体来说,Cloneable 接口没有指定 clone() 方法,clone() 方法是从 Object 类继承的。...标记接口不包含任何方法,标记接口唯一的作用就是允许在类型查询中使用 instanceof:if (obj instanceof Cloneable) {}建议你自己的程序中不要使用标记接口。...下面来看创建深拷贝的 done() 方法的一个例子:class Employee implements Cloneable { // ...

    64410

    详解Java中的clone方法 -- 原型模式

    1 使用new操作符创建一个对象  2 使用clone方法复制一个对象  那么这两种方式有什么相同和不同呢? new操作符的本意是分配内存。...分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始化,构造方法返回后,一个对象创建完毕,可以把他的引用(地址)发布到外部,在外部就可以使用这个引用操纵这个对象。...Person p1 = p;         System.out.println(p);         System.out.println(p1);  当Person p1 = p;执行之后, 是创建了一个新的对象吗...,也就是说创建了新的对象, 而不是把原对象的地址赋给了一个新的引用变量:  com.pansoft.zhangjg.testclone.Person@2f9ee1ac com.pansoft.zhangjg.testclone.Person...真的是深拷贝吗   由上一节的内容可以得出如下结论:如果想要深拷贝一个对象, 这个对象必须要实现Cloneable接口,实现clone方法,并且在clone方法内部,把该对象引用的其他对象也要clone

    40600

    详解Java中的clone方法:原型模式

    那么在java语言中,有几种方式可以创建对象呢? 1 使用new操作符创建一个对象 2 使用clone方法复制一个对象 那么这两种方式有什么相同和不同呢? new操作符的本意是分配内存。...分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的 初始化,构造方法返回后,一个对象创建完毕,可以把他的引用(地址)发布到外部,在外部就可以使用这个引用操纵这个对象。...,也就是说创建了新的对象, 而不是把原对象的地址赋给了一个新的引用变量: com.pansoft.zhangjg.testclone.Person@2f9ee1ac com.pansoft.zhangjg.testclone.Person...真的是深拷贝吗 由上一节的内容可以得出如下结论:如果想要深拷贝一个对象, 这个对象必须要实现Cloneable接口,实现clone方法,并且在clone方法内部,把该对象引用的其他对象也要clone一份...深拷贝和彻底深拷贝,在创建不可变对象时,可能对程序有着微妙的影响,可能会决定我们创建的不可变对象 是不是真的不可变。clone的一个重要的应用也是用于不可变对象的创建。

    74910

    深入浅出Java中的clone克隆方法,写得太棒了!

    使用new操作符创建一个对象 使用clone方法复制一个对象 那么这两种方式有什么相同和不同呢? new操作符的本意是分配内存。...分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始化,构造方法返回后,一个对象创建完毕,可以把他的引用(地址)发布到外部,在外部就可以使用这个引用操纵这个对象。...而clone在第一步是和new相似的, 都是分配内存,调用clone方法时,分配的内存和源对象(即调用clone方法的对象)相同,然后再使用原对象中对应的各个域,填充新对象的域, 填充完成之后,clone...真的是深拷贝吗 通过上面的讲解我们已经知道: 如果想要深拷贝一个对象, 这个对象必须要实现Cloneable接口,实现clone方法,并且在clone方法内部,把该对象引用的其他对象也要clone一份...深拷贝和彻底深拷贝,在创建不可变对象时,可能对程序有着微妙的影响,可能会决定我们创建的不可变对象是不是真的不可变。clone的一个重要的应用也是用于不可变对象的创建。

    53340

    Java基础——clone()方法浅析

    使用new操作符创建一个对象 使用clone方法复制一个对象    那么这两种方式有什么相同和不同呢? new操作符的本意是分配内存。...分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始化,构造方法返回后,一个对象创建完毕,可以把他的引用(地址)发布到外部,在外部就可以使用这个引用操纵这个对象。..."); 2 Person p1 = p; 3 4 System.out.println(p); 5 System.out.println(p1);  当Person p1 = p;执行之后, 是创建了一个新的对象吗...,也就是说创建了新的对象, 而不是把原对象的地址赋给了一个新的引用变量:    com.pansoft.zhangjg.testclone.Person@2f9ee1ac   com.pansoft.zhangjg.testclone.Person...但是,clone()方法在执行其动作之前必须先检查class是否实现了Cloneable接口。Cloneable接口和Serialiable接口一样是一个标记接口,没有任何内容。

    64490

    Java中clone( )和new效率哪个更高?

    对象创建的几种方法: 使用new关键字 使用clone方法 反射机制 反序列化 以上四种都可以产生java对象 1,3都会明确的显式的调用构造函数 2是在内存上对已有对象的影印 所以不会调用构造函数 4...拷贝对象返回的是一个新的对象,而不是一个对象的引用地址; 拷贝对象已经包含原来对象的信息,而不是对象的初始信息,即每次拷贝动作不是针对一个全新对象的创建。 clone()和new那个更快?...前提是类实现Cloneable接口,Cloneable接口没有任何方法,是一个空接口,也可以称这样的接口为标志接口,只有实现了该接口,才会支持clone操作。...Object中有一个clone方法,为什么还必须要实现Cloneable接口呢,这就是cloneable接口这个标志接口的意义,只有实现了这个接口才能实现复制操作, 因为jvm在复制对象的时候,会检查对象的类是否实现了...关于这方面的问题,网上有很多的相关知识了,不再累述了。 由于通过复制操作得到对象不需要调用构造函数,只是内存中的数据块的拷贝,那是不是拷贝对象的效率是不是一定会比new的时候的快。 答案:不是。

    1.1K10

    聊一下深浅克隆的那些要点

    所以说在Java中我们可以通过Clone方法来创建一个新的对象,这里让我们来回顾一下创建新对象的几种创建方式:使用new关键字调用构造函数反射调用构造函数使用clone方法没有调用构造函数使用反序列化没有调用构造函数浅克隆将源对象中为基本数据类型的成员变量的属性都复制给克隆对象...在上面的注释的大意就是,一个类要想使用clone()方法必须实现Cloneable接口,否则抛出CloneNotSupportedException异常。...=x 应当返回 true,因为克隆对象与原对象不是同一个对象;对于所有对象来说,x.clone().getClass() == x.getClass() 应当返回 true,因为克隆对象与原对象的类型是一样的...实现深克隆的方法:所有对象都实现克隆方法;通过构造方法实现深克隆;使用 JDK 自带的字节流实现深克隆;实现浅克隆,代码实战实现Cloneable接口,并且必须重写clone方法,因为clone方法被protected...String,有些同学可能有疑问了这不也是一个对象类型吗?

    37230

    Java Code Review清单

    整洁的代码 清单项目 分类 使用可以表达实际意图(Intention-Revealing)的名称 有意义的名称 每一个概念只用一个词 有意义的名称 使用方案/问题领域名称 有意义的名称 类应该是比较小的...,而不是null 方法 最小化类和成员的可访问性 类和接口 在pulibc类中,使用访问器方法(accessor methods)(译者注:访问器方法即我们平常用的get/set方法)而不是public...域 类和接口 最小化本地变量的范围 综合编程 通过接口引用对象 综合编程 遵循广泛接受的命名规则 综合编程 避免使用finalizer 创建和销毁对象 当你重写equals时总是重写hashCode 综合编程...总是重写toString 综合编程 使用枚举来代替int常量 枚举和注解(Annotations) 使用标记接口(marker interface)(译者注:标记接口是一种没有任何行为的接口,实现它只是为了让实现类属于某种类型...,如JDK中的Serializable,Cloneable等)来定义类型 枚举和注解(Annotations) 对共享可变的数据使用同步访问 并发 使用executors而不是task和thread 并发

    74320

    克隆一个对象——原型模式深入解析

    在以上clone方法体中,我们手动将属性值重新set进clone出来的对象中,但是如果对象的属性特别多怎么办,我们要一个一个手动去set吗?...java使用clone()的方法和约束 克隆的类要实现Cloneable接口。...浅克隆就是只将值类型的变量复制过去,而引用类型只是复制过去引用。 深克隆是把值类型和引用类型的变量均开辟一块新的内存区域复制一份出来。...由此可以看出,如果使用浅克隆,原对象的引用类型的变量发生改变的时候,克隆对象也发生变化,这绝不是我们想要的结果。 上面写到的就是浅克隆代码,那么我们在代码中查看,浅克隆会出现什么问题呢?...那就要让类去实现java.io.Serializable接口,而不是Cloneable接口了。

    74170

    面试官:你知道对象的克隆原理吗?

    简单来说,在浅复制中,当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制。 ?...外面的User对象克隆是成功了,但是克隆出来的对象中,引用类型的属性并没有克隆出来,还是使用同一个引用地址。 什么是深度复制?...关于序列化实现深度复制,请看这篇文章:面试官:说说你对序列化的理解 案例 下面使用Object的clone方法和实现Cloneable接口,写一个深度复制案例: 先创建一个用户地址类: public...否则,此方法会创建此对象的类的一个新实例,并像通过分配那样,严格使用此对象相应字段的内容初始化该对象的所有字段;这些字段的内容没有被自我复制。...这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。

    47720

    Effective.Java 读书笔记(11)关于clone方法

    的异常 一个接口这样被使用是极其罕见的,从未见过其他的接口有这样的作用 一般来说,实现一个接口是用来让这个能够做某些事情,而Cloneable则是修改了父类的protected方法的实现,如果实现Cloneable...,这里的clone方法将返回的是PhoneNumber这个类的实例,而不是Object,如果是在1.5版本中,这样做是合法的并且希望你去这么做,这被称为协变返回类型(covariant return types...,当然,这里有些特例,举个例子,一个域代表一序列数值或者特殊的id,又或者是一个对象创建的次数之类的,对这些域就要进行修正 上述这些复杂的东西都是必要的吗?...,Cloneable由于缺少一个public的clone方法而失去接口的作用,因此你并不会放弃接口而去使用复制构造函数或者是复制工厂 此外,一个复制构造函数或者复制工厂能够接受一个是这个类所实现的接口类型的参数...以接口为基的复制构造函数或者构造工厂,更加合适的叫法就是转换构造函数(conversion constructors)或者转换工厂(conversion factories),这样我们就可以选择复制的实例所实现的类型而不是强制用户使用原始实现的类型

    45620

    23种设计模式(八)-原型设计模式

    原型设计模式的精髓也在于此. 原型模式用于创建重复的对象,首先创建一个实例对象, 然后通过拷贝实例对象创建一个新的对象。这种模式类似于创建型模式。...使用原型模式创建对象非常高效,无须知道对象创建的细节.多用于创建复杂的或者构造耗时的实例,因为在这种情况下,复制一个已经存在的实例会更高效。 1.2 为什么要使用原型设计模式?...Cloneable接口: 在Java语言中有一个自带的Cloneable接口, 这个接口的作用只有一个, 就是在程序运行的时候通知虚拟机可以安全的在实现了此接口的类上使用clone()方法....原型设计模式实现的类型有两种: 浅拷贝和深拷贝 4.1 浅拷贝 浅拷贝指的是在创建一个对象的时候, 新对象的属性和原来对象的属性完全相同, 对于非基本类型属性, 扔指向原有属性所指向的对象的内存地址。...第一个返回结果是false。说明克隆后重新创建了一个对象。 第二个结果返回的是ture,说明克隆后引用类型的对象指向了原来对象的地址。 这是一种浅拷贝, 默认的拷贝方式是浅拷贝。

    64630

    深入浅出Java中的clone克隆方法,写得太棒了!

    使用new操作符创建一个对象 使用clone方法复制一个对象 那么这两种方式有什么相同和不同呢? new操作符的本意是分配内存。...分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始化,构造方法返回后,一个对象创建完毕,可以把他的引用(地址)发布到外部,在外部就可以使用这个引用操纵这个对象。...而clone在第一步是和new相似的, 都是分配内存,调用clone方法时,分配的内存和源对象(即调用clone方法的对象)相同,然后再使用原对象中对应的各个域,填充新对象的域, 填充完成之后,clone...真的是深拷贝吗 通过上面的讲解我们已经知道: 如果想要深拷贝一个对象, 这个对象必须要实现Cloneable接口,实现clone方法,并且在clone方法内部,把该对象引用的其他对象也要clone一份...深拷贝和彻底深拷贝,在创建不可变对象时,可能对程序有着微妙的影响,可能会决定我们创建的不可变对象是不是真的不可变。clone的一个重要的应用也是用于不可变对象的创建。

    30670

    笔记《Effective Java》02:对所有对象都通用的方法

    如果满足下述条件中的一个,不重写equals方法就是合理的:该类的每个实例在本质上都是唯一的。对于诸如Thread这样代表活动实体而不是值的类来说,这是成立的。该类没有必要提供一个“逻辑相等”的测试。...如:public boolean equals(MyClass o) { }该方法只是重载了equals方法,而不是重写。应该强制使用@Override注解,在编译期间会告知我们哪里出错了。...toString方法的一个实现,但他返回的字符串通常不是类的用户所希望看到的。...提供一个好的toString实现可以让类用起来更舒适,使用该类的系统也更容易调试如果条件允许,toString方法应该返回当前对象中包含的所有有意义的信息无论是否决定指定格式,都应该在文档中清晰地表明自己的意图借助...5、谨慎重写clone方法Cloneable 接口的设计初衷是作为一个混合接口,用来表明类支持克隆功能。

    7210

    我要拷贝你—Java对象

    包括 类,接口和数组 。引用类型在声明时只是给变量分配了引用空间,并不分配数据空间。 相等就是拷贝吗? 好了,了解了基础知识后,开始今天的拷贝问题。拷贝是什么呢?是用等号就可以完成的操作吗?...我们可以发现,其实=并不是拷贝了对象,而是直接使用了usera对象的引用地址,也就是说usera和userb其实是一个人,没有拷贝。...浅拷贝 两步,完成对象的拷贝(浅拷贝) 实现Cloneable接口 重写clone方法 public class User2 implements Cloneable { private...所以,大概了解了: 浅拷贝意思就是只拷贝对象中的基本数据类型,而引用数据类型还是引用传递,没有创建一个新的对象, 其实就是值传递+引用传递 那深拷贝呢就是对其中的引用数据类型进行拷贝的时候,创建了一个新的对象...总结 浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝。 深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。

    47230

    Java基础面试题&知识点总结(上篇)

    深拷贝(Deep Copy):当进行深拷贝时,无论对象中的字段是基本类型还是引用类型,都会创建一个新的副本。对于引用类型,会复制引用指向的对象,而不仅仅是复制引用。...为什么说 Cloneable 是一个标记接口? Cloneable 接口被称为标记接口,是因为它本身并没有定义任何方法,它的作用主要是为了标记一个类的对象可以被克隆。...静态字段属于类,而不是对象。transient 关键字告诉 JVM 该字段不应该被序列化。 ---- 2.4、Java数据类型相关 问题 18. Java 中的基本数据类型有哪些?...例如,当你连接两个字符串时,实际上是创建了一个新的字符串,而不是修改原始字符串。...如果你使用 == 操作符比较这两个字符串,可能会得到 false,因为 == 操作符比较的是对象的引用,而不是内容。

    29710
    领券