`

Java基础:深入 JAVA对象的复制与比较

    博客分类:
  • java
阅读更多

1.对象的复制
2.clone()的使用
3.对象实例的比较
////////////////////
//
/////////////////////


1.对象的复制

 

String str1 = "This is a string!"  //这里是 "对象引用" 的复制
String str2 = new String(str1);  //这里是 "对象实例" 的复制

浅复制: 只复制复合对象本身.
深复制: 除了复制复合对象本身, 还复制了复合对象的引用的对象实例.

例如:

class Pupil{
    public Pupil(String sno, String name, int age){
        this.sno = new String(sno);
        this.name = new String(name);
        this.age = age;
    }

    public String getSno() {
        return sno;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    private String sno;
    private String name;
    private int age;
}

public class CopyDemo {
    public static Pupil[] shallowCopy(Pupil[] aClass) {
        Pupil[] newClass = new Pupil[aClass.length];

        //此时newClass 与aClass 指向同一块内存
        for(int i=0; i
            newClass[i] = aClass[i];
        return newClass;
    }

    public static Pupil[] deepCopy(Pupil[] aClass) {
        Pupil[] newClass = new Pupil[aClass.length];

        //此时newClass 与aClass 的相应sno , name 指向同一块内存
        for(int i=0; i
            String sno = aClass[i].getSno();
            String name = aClass[i].getName();
            int age = aClass[i].getAge();
            newClass[i] = new Pupil(sno, name, age);
        }

        return newClass;
    }

    public static Pupil[] deeperCopy(Pupil[] aClass) {
        Pupil[] newClass = new Pupil[aClass.length];

        //完全的复制
        for(int i=0; i
            String sno = new String(aClass[i].getSno());
            String name = new String(aClass[i].getName());
            int age = aClass[i].getAge();
            newClass[i] = new Pupil(sno, name, age);
        }

        return newClass;
    }
}

 

2.clone()的使用

* Object.clone()
* Cloneable 接口
* CloneNotSupportedException

a. 使用Object.clone 进行复制
两个必须条件:
1.一定要将重定义后的clone() 方法定义为公有方法(在Object 类中, 它是受保护的成员,    不能直接使用)
2.该后代类声明实现接口 Cloneable 接口(当类实现该接口, 其任何子类也会继承该接口), 该接口实际上没有任何
  内容, 只是一个标识, 标志实现该接口的类提供clone() 方法.(这是接口的一种非典型用法)

public class Fraction implements Cloneable {
    public Object clone() {
        try{
            return super.clone();  //call protected method
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }
    //other methods ...
}


b.重写Object.clone()
例如对   private char[] cb; character buffer 进行复制

// add in class Cirbuf
        public Object clone() {
        try{
            Cirbuf copy = (Cirbuf)super.clone();
            copy.cb = (char[])cb.clone();
            return copy;
        }catch (CloneNotSupportedException e){
            throw new InternalError(e.toString());
        }
    }

c.复制数组
  数组是在方法调用重以引用的形式传递的对象. 下述情况下非常适合引用来传递数组:
  *正在接收的方法不修改数组
  *正在调用的方法不必关心是否修改数组
  *正在调用的方法想要得到数组中的修改结果
  否则, 就应该在方法调用中传递数组对象的副本. 只需调用 arrObj.clone() 方法即可完成数组arrObj 的复制操作. 随后将该数组副本强制转换为其正确类型:
      (type[])arrObj.clone();
   System.arraycopy 方法提供一种用于在数组间复制多个元素的有效方式.
        System.arraycopy(source, i, target, j, len)


3.对象实例的比较

例如:

    Pupil p1 = new Pupil("99184001", "zhang3", 18);
    Pupil p2 = new Pupil("99184001", "zhang3", 18);

a. "=="
   if(p1 == p2)...
  此次测试的是对象引用, 其结果肯定是false, 只要两个对象引用不是互为别名就不会相等.
b. 浅比较  false

   if(p1.getSno() == p2.getSno() && p1.getName() == p2.getName()
     && p1.getAge() == p2.getAge()) ...;

c. 深比较   true[/code]
  if(p1.getSno().equals(p2.getSno()) && p1.getName().equals(p2.getName())
     && p1.getAge() == p2.getAge()) ...;[/code]
    JAVA API 的跟类Object 也提供了equals() 方法, 但它只是比较两个对象引用, 而非比较两个对象实例.
    不管怎样, 如果需要比较Pupil 类的对象(例如要将它们放入对象容器), 应该为Pupil 类重定义equals() 方法:

    public boolean equals(Object otherobj) {
        //检查otherobj 是否为空
        if(otherobj == null) return false;

        //检查otherobj 是否就是当前对象
        if(otherobj == this) return true;

        //检查otherobj 是否具有正确的类型, 即检查是否可与当前对象比较
        if(!(otherobj instanceof Pupil)) return false;

        //将otherobj 转换为Pupil 类的对象引用
        Pupil tmpObj = (Pupil)otherobj;
        //关于学生是否相等的逻辑检查
        if(sno.equals(tmpObj.sno) && name.equals(tmpObj.name)
             && age == tmpObj.age) return true;

        return false;
    }

   JAVA API 所提供的每个类几乎都提供了采用深比较策略的equals() 方法, 例如String 类equals() 方法. 一般来说, 用户自己定义的类也应当提供合适的equals() 方法, 特别是当程序要将其对象放入JAVA API 所提供的对象容器类的时候.
   按照约定, 任何类所提供的equals() 方法所实现的相等比较应该是等价关系, 即满足自反性, 对称性和传递性. 另外一个类重定义了equals() 方法, 也应该重定义相应hashCode() 方法, 否则将这个类的对象放入映射对象容器时也会发生以外.

分享到:
评论

相关推荐

    java不同对象及集合的多次复制

    在Java编程中,对象复制是一项常见的任务,特别是在处理模型(Model)和视图对象(VO)时。模型对象通常用于封装业务数据,而视图对象则用于展示这些数据。值复制,即对象属性值的复制,是保持数据一致性和简化代码...

    Java基础课件 全套pdf版 java培训

    这套Java基础课件全面覆盖了Java编程的基础知识,通过系统学习,读者将能够掌握Java编程的基本技能,为更深入的Java开发打下坚实的基础。在学习过程中,理论结合实践,多做练习,将是掌握这些知识点的关键。

    分布式java应用:基础与实践

    本篇内容将深入探讨分布式Java应用的基础概念、设计原则以及实战技巧。 1. 分布式系统概述 分布式系统是由多台独立的计算机节点通过网络相互连接,共同协作完成一个单一任务的系统。这些节点之间通过网络通信,...

    深入java虚拟机.pdf

    深入 Java 虚拟机.pdf Java 虚拟机(Java Virtual Machine,JVM)是 Java 语言的 runtime 环境,是 Java 程序执行的核心组件。它提供了一个平台无关的环境,允许 Java 程序在不同的操作系统和硬件平台上运行。 一...

    java类复制一个持久化对象

    在Java编程语言中,对象复制是一项常见的操作,尤其是在处理持久化对象时,为了保持数据的一致性和完整性,正确地复制对象变得尤为重要。本文将深入探讨如何利用反射机制在Java中复制一个持久化对象,理解其背后的...

    java复制文件代码

    根据提供的文件标题、描述、标签以及部分内容,我们可以总结出与“Java复制文件代码”相关的重要知识点。虽然提供的代码片段存在一些未完成的部分和注释掉的代码,但是我们仍然可以从中提取有价值的信息,并且深入...

    Java面向对象(基础)

    根据给定的文件信息,我们可以总结出以下关于Java面向对象的基础知识点: ### 1. Java的可移植性 - **实现原理**:Java语言的可移植性主要...通过理解这些概念,可以为后续深入学习Java面向对象编程打下坚实的基础。

    java基础教学全套课件_pdf_ppt

    接着,深入学习类与对象,这是Java面向对象编程的核心。类是具有相同属性和行为的对象模板,它定义了对象的结构和操作。对象则是类的实例,拥有类定义的属性和方法。封装、继承和多态是面向对象的三大特性,封装使得...

    Java 基础ppt.zip

    通过这些知识点的学习,初学者将能够建立起坚实的Java编程基础,为进一步深入学习Java EE、Android开发或大数据处理等方向打下坚实基础。这个PPT是IT新手系统学习Java的理想资源,以通俗易懂的方式呈现,确保了学习...

    JAVA_对象克隆

    在Java编程语言中,对象克隆是一种创建与现有对象具有相同数据的新对象的过程。这个过程在需要复制对象的所有属性而不创建新类型实例时非常有用。本文将深入探讨Java中的对象克隆,包括其原理、实现方式以及注意事项...

    编程语言java对象复制.pdf

    在标题“编程语言java对象复制.pdf”和描述“编程语言java对象复制.pdf”中,明确指出了文档的主题是关于Java编程语言中对象复制的技术知识。在给出的内容部分中,通过具体的Java代码示例,讨论了在Java中实现对象...

    Java 并发核心编程

    - **定义**: 每个Java对象都有一个与其关联的monitor,用于控制对该对象关键代码段的访问。 - **用途**: 使用`synchronized`关键字来标识关键代码段或方法,确保同一时间只有一个线程可以执行这些代码。 - **协作...

    深入JAVA虚拟机完整教程

    Java虚拟机(JVM)是Java编程语言的核心组成部分,它为Java程序提供了运行环境。深入理解JVM对于优化代码性能、解决内存问题以及提升...通过阅读"深入JAVA虚拟机完整教程",你可以全面了解并掌握这些关键概念和技术。

    think in java 第11章 持有对象

    以上就是《Think in Java》第11章“持有对象”中的核心知识点,理解并掌握这些概念对于深入理解和使用Java对象是非常重要的。通过实践和编程练习,你可以更好地领悟这些知识,并应用到实际项目中。

    Java核心技术 PDF(文字版 有目录 可以复制粘贴文字)

    1. **Java语言基础**:包括Java的安装与配置、基本语法如变量、常量、数据类型、运算符、流程控制语句(if-else、switch、for、while等)以及方法的定义和调用。 2. **面向对象编程**:深入讲解类、对象、封装、...

    java文件复制,实现文件的复制

    本文将深入探讨如何使用Java实现文件及其目录结构的完整复制。 #### 一、基础知识回顾 在进行文件复制之前,我们先回顾一下Java中处理文件的基本概念: 1. **`java.io.File`**:用于表示文件或目录路径,可以获取...

    Java程序设计课件:第三章 类与对象的深入理解.ppt

    在Java编程语言中,类和对象是核心概念,它们构成了面向对象编程的基础。第三章“类与对象的深入理解”主要涵盖了以下几个知识点: 1. **对象的引用和实体**: - 在Java中,对象分为两个部分:引用(Reference)和...

    java对象复制[参考].pdf

    本文将深入探讨Java对象复制,特别是通过`clone()`方法实现的复制。 首先,我们来理解什么是对象复制。对象复制是指创建一个新对象,这个新对象与原对象具有相同的属性值。在Java中,基础类型(如int、double等)是...

    JAVA【第5章:面向对象基础】_String类的常用方法.rar

    在Java编程语言中,面向对象基础是学习Java的基石,而`String`类则是最常用的类之一,几乎在每一个程序中都会见到它的身影。本章节将深入探讨`String`类的常用方法,帮助你更好地理解和运用这个核心组件。 `String`...

    各种JAVA基础及框架

    本节我们将基于提供的笔记内容,深入探讨Java的基础知识和相关技术框架。 ##### Unix/Linux操作系统操作 在进行Java开发时,掌握基本的Unix/Linux命令是非常必要的。例如: - **inode**: inode是文件系统的内部数据...

Global site tag (gtag.js) - Google Analytics