【IT领域新生必看】探索Java中的对象创建:深入理解`new`与`clone`的对比

文章目录

    • 引言
    • 什么是`new`关键字?
      • 使用`new`关键字的基本语法
        • 示例:
    • 什么是`clone`方法?
      • 使用`clone`方法的基本语法
        • 示例:
    • `new`与`clone`的区别
      • 内存分配与初始化
      • 调用方式
      • 适用场景
      • 性能
    • `new`关键字的优缺点
      • 优点
      • 缺点
    • `clone`方法的优缺点
      • 优点
      • 缺点
    • 深入理解`clone`:浅复制与深复制
      • 浅复制
        • 示例:
      • 深复制
        • 示例:
    • 选择合适的对象创建方式
      • 何时使用`new`关键字
      • 何时使用`clone`方法
    • 总结

在这里插入图片描述

引言

在Java编程中,创建对象是一个基础而关键的操作。newclone是两种常见的对象创建方式,它们各有优缺点,适用于不同的场景。对于初学者来说,理解这两种方法的区别和应用场景,是掌握Java编程的重要一步。本篇文章将详细比较newclone操作对象的原理、用法及其优缺点,帮助你全面理解这两种对象创建方式。

什么是new关键字?

new关键字是Java中最常用的对象创建方式。它通过调用类的构造方法来创建一个新的对象,并在内存中为该对象分配空间。

使用new关键字的基本语法

创建对象的基本语法如下:

ClassName objectName = new ClassName(arguments);
示例:
class Dog {String name;Dog(String name) {this.name = name;}void bark() {System.out.println(name + " is barking");}
}public class Main {public static void main(String[] args) {Dog dog = new Dog("Buddy");dog.bark();  // 输出:Buddy is barking}
}

在上述示例中,new Dog("Buddy") 调用 Dog 类的构造方法,创建了一个新的 Dog 对象。

什么是clone方法?

clone方法是一种特殊的对象创建方式,用于复制现有对象。通过实现 Cloneable 接口并重写 clone() 方法,可以创建当前对象的一个副本。

使用clone方法的基本语法

使用clone方法创建对象的基本步骤如下:

  1. 实现 Cloneable 接口。
  2. 重写 clone() 方法。
  3. 调用 clone() 方法创建对象副本。
示例:
class Sheep implements Cloneable {String name;Sheep(String name) {this.name = name;}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}void bleat() {System.out.println(name + " is bleating");}
}public class Main {public static void main(String[] args) {try {Sheep originalSheep = new Sheep("Dolly");Sheep clonedSheep = (Sheep) originalSheep.clone();clonedSheep.bleat();  // 输出:Dolly is bleating} catch (CloneNotSupportedException e) {e.printStackTrace();}}
}

在上述示例中,通过 clone() 方法创建了一个 Sheep 对象的副本。

newclone的区别

内存分配与初始化

  • new关键字:调用构造方法创建新对象,并在内存中分配新的空间。每次创建的新对象都是独立的,其内部状态由构造方法初始化。
  • clone方法:复制现有对象的内存状态,创建一个新对象,并将原对象的所有字段复制到新对象中。新对象与原对象有相同的初始状态。

调用方式

  • new关键字:显式调用构造方法来创建对象。例如,new Dog("Buddy")
  • clone方法:调用现有对象的 clone() 方法来创建对象副本。例如,originalSheep.clone()

适用场景

  • new关键字:适用于需要创建新对象,并通过构造方法初始化对象状态的场景。
  • clone方法:适用于需要复制现有对象,并保留其内部状态的场景。

性能

  • new关键字:通常稍慢,因为它需要调用构造方法,并进行所有初始化操作。
  • clone方法:通常较快,因为它直接复制内存中的对象状态,但可能需要额外的深度复制操作,增加复杂性。

new关键字的优缺点

优点

  1. 简单明了new关键字的使用非常直观,易于理解和使用。
  2. 灵活性:可以通过构造方法灵活初始化对象的状态。
  3. 标准化:是Java标准的对象创建方式,广泛应用于各种场景。

缺点

  1. 性能开销:每次创建新对象都需要调用构造方法,可能导致性能开销。
  2. 重复代码:对于相同的初始化逻辑,可能需要多次编写相同的构造方法。

clone方法的优缺点

优点

  1. 快速创建对象:通过内存复制创建对象副本,速度通常较快。
  2. 保留对象状态:可以保留原对象的内部状态,适用于需要复制对象的场景。

缺点

  1. 复杂性:需要实现 Cloneable 接口,并处理可能的 CloneNotSupportedException 异常。
  2. 浅复制问题:默认的 clone() 方法是浅复制,可能导致共享内部对象,需要额外处理深度复制。

深入理解clone:浅复制与深复制

在使用 clone 方法时,理解浅复制和深复制的区别非常重要。

浅复制

浅复制仅复制对象本身,而不复制对象内部引用的其他对象。新对象与原对象共享内部引用对象。

示例:
class Address implements Cloneable {String city;Address(String city) {this.city = city;}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}class Person implements Cloneable {String name;Address address;Person(String name, Address address) {this.name = name;this.address = address;}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}public class Main {public static void main(String[] args) {try {Address address = new Address("New York");Person originalPerson = new Person("John", address);Person clonedPerson = (Person) originalPerson.clone();System.out.println(originalPerson.address.city);  // 输出:New YorkSystem.out.println(clonedPerson.address.city);   // 输出:New YorkclonedPerson.address.city = "Los Angeles";System.out.println(originalPerson.address.city);  // 输出:Los AngelesSystem.out.println(clonedPerson.address.city);   // 输出:Los Angeles} catch (CloneNotSupportedException e) {e.printStackTrace();}}
}

在上述示例中,浅复制导致原对象和克隆对象共享同一个 Address 对象。

深复制

深复制不仅复制对象本身,还递归复制对象内部引用的所有对象。新对象与原对象完全独立。

示例:
class Address implements Cloneable {String city;Address(String city) {this.city = city;}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}class Person implements Cloneable {String name;Address address;Person(String name, Address address) {this.name = name;this.address = address;}@Overrideprotected Object clone() throws CloneNotSupportedException {Person clonedPerson = (Person) super.clone();clonedPerson.address = (Address) address.clone();return clonedPerson;}
}public class Main {public static void main(String[] args) {try {Address address = new Address("New York");Person originalPerson = new Person("John", address);Person clonedPerson = (Person) originalPerson.clone();System.out.println(originalPerson.address.city);  // 输出:New YorkSystem.out.println(clonedPerson.address.city);   // 输出:New YorkclonedPerson.address.city = "Los Angeles";System.out.println(originalPerson.address.city);  // 输出:New YorkSystem.out.println(clonedPerson.address.city);   // 输出:Los Angeles} catch (CloneNotSupportedException e) {e.printStackTrace();}}
}

在上述示例中,通过重写 clone() 方法实现深复制,使原对象和克隆对象的 Address 对象完全独立。

选择合适的对象创建方式

在实际开发中,根据具体需求选择合适的对象创建方式可以提高代码的效率和可维护性。

何时使用new关键字

  • 创建全新对象:需要通过构造方法初始化新对象时,使用 new 关键字。
  • 简单场景:对象创建逻辑简单,不需要复制现有对象时,使用 new 关键字。

何时使用clone方法

  • 复制现有对象:需要保留原对象状态,创建其副本时,使用 clone 方法。
  • 性能需求:在性能要求较高的场景

中,使用 clone 方法可以快速复制对象。

总结

newclone是Java中两种常见的对象创建方式,它们各有优缺点,适用于不同的场景。通过本文的介绍,你应该对这两种方法的区别、应用场景及其优缺点有了全面的了解。希望你在编程的学习过程中不断进步,成为一名出色的程序员!

无论你选择哪种对象创建方式,记住多多练习,积累经验,这将成为你编程旅程中的得力助手。祝你编程愉快!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/867065.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大华设备接入GB28181视频汇聚管理平台EasyCVR安防监控系统的具体操作步骤

智慧城市/视频汇聚/安防监控平台EasyCVR兼容性强,支持多协议接入,包括国标GB/T 28181协议、GA/T 1400协议、部标JT808协议、RTMP、RTSP/Onvif协议、海康Ehome、海康SDK、大华SDK、华为SDK、宇视SDK、乐橙SDK、萤石云SDK等,并能对外分发RTMP、…

Pseudo-Label : The Simple and Efficient Semi-Supervised Learning Method--论文笔记

论文笔记 资料 1.代码地址 https://github.com/iBelieveCJM/pseudo_label-pytorch 2.论文地址 3.数据集地址 论文摘要的翻译 本文提出了一种简单有效的深度神经网络半监督学习方法。基本上,所提出的网络是以有监督的方式同时使用标记数据和未标记数据来训练的…

加法器的基本操作

基本单元 与门(AND) 全1为1,有0为0 或门(OR) 全0为0,有1为1 非门(NOT) 为1则0,为0则1 异或门(XOR) 两个输入端,相同为0,不同为1 与非门(NADD) 全1为0,有0为1 或非门(NOR) 全0为1,有1为0。刚…

redis 如何使用 scan, go语言

建议用方案乙 文章目录 场景方案方案甲方案乙 拓展 场景 redis 中存在大量 key。 其中有一部分是用户登陆的 session_id, 结构是 : session_id:1session_id:2session_id:3需求: 有多少用户在线 方案 方案甲 keys session_id:*这种方式简…

第一次面试的经历(java开发实习生)

面试官的问题 我想问一下你这边有做过什么项目吗?你方便讲一下你做过的那些项目吗,用了什么技术栈,包括你负责开发的内容是什么?(项目经验)八大基本数据类型是什么?(基础)你说一下…

安徽医学期刊

《安徽医学》(月刊) 主管单位:安徽省卫生健康委员会 主办单位:安徽省医学情报研究所 承办单位:安徽省医学会 收录情况:中国科技论文统计源期刊(中国科技核心期刊)、中国核心期刊&…

项目部署_持续集成_Jenkins

1 今日内容介绍 1.1 什么是持续集成 持续集成( Continuous integration , 简称 CI )指的是,频繁地(一天多次)将代码集成到主干 持续集成的组成要素 一个自动构建过程, 从检出代码、 编译构建…

SQL FOREIGN KEY

SQL FOREIGN KEY 简介 SQL(Structured Query Language)是用于管理关系数据库管理系统(RDBMS)的标准编程语言。在SQL中,FOREIGN KEY是一个重要的概念,用于建立和维护数据库中不同表之间的关系。本文将详细介绍SQL FOREIGN KEY的概念、用途、以及如何在SQL中实现和使用FO…

数据结构——单向循环链表

文章目录 1. 概念 2. 区别 2.1 结构区别 2.2 访问方式区别 2.3 优缺点对比 3. 流程 4. 基本操作 5. 代码示例 1. 概念 单向循环链表是一种特殊的单链表,其中最后一个节点的后继指针指向头节点,形成一个环。单向循环链表适合用于需要循环访问数据…

Spring Boot集成jacoco实现单元测试覆盖统计

1.什么是jacoco? JaCoCo,即 Java Code Coverage,是一款开源的 Java 代码覆盖率统计工具。支持 Ant 、Maven、Gradle 等构建工具,支持 Jenkins、Sonar 等持续集成工具,支持 Java Agent 技术远程监控 Java 程序运行情况…

【鸿蒙学习笔记】Stage模型工程目录

官方文档:应用配置文件概述(Stage模型) 目录标题 FA模型和Stage模型工程级目录模块级目录app.json5module.json5程序执行流程程序基本结构开发调试与发布流程 FA模型和Stage模型 工程级目录 模块级目录 app.json5 官方文档:app.j…

STM32学习历程(day3)

通过GPIO点灯 首先先创建工程 这步比较繁琐 可以去参考江协科技[3-2]章节 想要驱动LED灯 要先使能时钟、然后再初始化、GPIO模式、引脚、以及输出速率 可以查看RCC的头文件 能看到三个使能函数 使能AHB、APB2、APB1 ,GPIO用APB2这个函数、 通过看RCC库函数的源码…

Memcached跨数据中心复制:高效数据同步的艺术

标题:Memcached跨数据中心复制:高效数据同步的艺术 Memcached是一个高性能的分布式内存缓存系统,广泛用于提升大规模Web应用的性能。在多数据中心的环境中,跨数据中心的数据复制是确保数据一致性和高可用性的关键技术。本文将深入…

给我的 IM 系统加上监控两件套:【Prometheus + Grafana】

监控是一个系统必不可少的组成部分,实时,准确的监控,将会大大有助于我们排查问题。而当今微服务系统的话有一个监控组合很火那就是 Prometheus Grafana,嘿你别说 这俩兄弟配合的相当完美,Prometheus负责数据采集&…

【MySQL系列】VARCHAR 类型详解及其使用策略

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

MySQL---事务管理

1.关于事务 理解和学习事务,不能只站在程序猿的角度来理解事务,而是要站在使用者(用户)的角度来理解事务。 比如支付宝转账,A转了B100块前,在程序猿的角度来看,是两条update操作,A …

ChatGPT对话:按ESC键退出Python程序

问:python,这条语句if keyboard.is_pressed(‘Esc’):会阻塞程序,等待按键吗? ChatGPT: if keyboard.is_pressed(Esc): 这条语句不会阻塞程序,它只是检查在执行这条语句时 Esc 键是否被按下。如果 Esc 键…

浅谈反射机制

1. 何为反射? 反射(Reflection)机制指的是程序在运行的时候能够获取自身的信息。具体来说,反射允许程序在运行时获取关于自己代码的各种信息。如果知道一个类的名称或者它的一个实例对象, 就能把这个类的所有方法和变…

react之错误边界

错误边界实质是指什么 实际上是组件 错误边界捕获什么时候的错误 在渲染阶段的错误 错误边界捕获的是谁的错误 捕获的是子组件的错误 错误边界不能捕获什么错误 1、不能捕获异步代码 2、不能捕获事件处理函数 3、不能捕获服务端渲染 4、不能捕获自身抛出的错误 错误…

百度amis vue3引入减少包提体积

不用amis的包 , 在index.html引入代码如下,要在main上面 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><link rel"icon" href"/favicon.ico" media"print"/><meta http…