30从零开始学Java之详解面向对象的7种创建方式

news2024/10/4 1:19:58

作者:孙玉昌,昵称【一一哥】,另外【壹壹哥】也是我哦

千锋教育高级教研员、CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者

前言

在上一篇文章中,壹哥给大家介绍了Java中的类及其特点、创建过程等内容,相信你现在已经知道该如何创建一个Java类了。接下来在本篇文章中,壹哥会继续带大家学习面向对象中关于对象的内容。其实类和对象作为面向对象中最基本,也是最重要的单元,两者可以说是形影不离的,所以请大家继续打起精神认真学习吧。

--------------------------------------------------前戏已做完,精彩即开始----------------------------------------------

全文大约【4700】字,不说废话,只讲可以让你学到技术、明白原理的纯干货!本文带有丰富的案例及配图视频,让你更好地理解和运用文中的技术概念,并可以给你带来具有足够启迪的思考......

配套开源项目资料

Github:

GitHub - SunLtd/LearnJava

Gitee:

一一哥/从零开始学Java

一. 对象简介

1. 概念

壹哥在之前的文章中,其实已经给大家解释过对象的概念了。在面向对象的编程规范中,“一切皆对象”,对象就是面向对象编程的核心。现实世界中的每一个物体都是对象!当然,这个“对象”不是你怀里撒娇的男/女朋友,而是指某个“类”的一个实例。

比如,“人”是一个“整体”的概念,它不是“个体”的概念,所以“人”是“类别(模板)”,而不是对象。但是在人这个“类别”中,有法外狂徒张三这个个体,张三就是一个具体的“对象”。每个对象都有自己的状态和行为,比如张三的状态有:身高、体重、爱好;行为有:吃、喝、piao、du、抽,坑、蒙、拐、骗、偷等。

本节配套视频链接如下:

Bilibili External Player

2. 行为和特征

一个对象主要包括行为和特征(状态、属性)两个核心要素。

行为:一般是动词,指的是方法,代表一个对象能干什么,具有哪些功能或能力,例如人可以吃饭、睡觉、说话、工作等;在Java中,一般是用方法来表明对象所具有的行为。

特征:也可以叫做状态,一般是名词,指的是属性,代表一个对象有什么特点或参数,例如每个人的姓名、年龄、性别、体重等。在Java中,一般是用变量来表明对象的状态。

3. 对象的创建方式(重点)

对象就是类的实例化,也就是根据类来创建一个具体的对象,就好比我们使用一个手机壳模具制造出一个具体的手机壳。接下来壹哥就给大家讲一下,在Java中创建对象的两种主要方式:显式创建与隐式创建

3.1 显式创建

其中显式创建对象时,又有以下4种具体的创建方式:

  • 使用new关键字创建对象;
  • 使用newlnstance()实例方法创建对象;
  • 使用clone()方法创建对象;
  • 使用ObjectlnputStream对象的readObject()方法创建对象。

3.2 隐式创建

隐式创建对象主要是包括以下几种方式:

  • 给String字符串变量赋值;
  • “+”号拼接多个字符串;
  • JVM虚拟机加载类时隐式创建类对象。

接下来壹哥分别给大家讲解一下这几种创建对象的方式。受限于篇幅,今天主要是给大家讲解通过new关键字创建对象的方式,其他的方式我们以后再细讲。

二. 显式创建

1. 使用new关键字创建对象

1.1 new简介

我们知道,new是"新的"的意思。在Java中,new是一个关键字,它用于创建一个新的类实例,即新的类对象。所以在Java中,创建新对象也可以叫做实例化对象对于引用类型来说,如果该类型没有进行实例化,也就是没有进行对象的创建,那么该对象的属性、方法等在内存中都是不存在的。只有使用new关键字创建了对象之后,这个对象在内存中才会存在,才能使用。

1.2 new作用

当一个引用类型的变量被声明以后,如果没有进行初始化,那么它就不指向任何对象,我们也就没办法使用该变量。所以我们就可以通过new关键字对该变量进行初始化,具体地来说,new关键字的作用如下:

  • 为新对象及对象中的各实例变量分配内存空间;
  • 将新对象中的各实例变量自动初始化成对应类型的默认值;
  • 初始化对象,并给各实例变量赋予正确的初始值;
  • 调用引用类型对应的构造方法;
  • 返回对象的引用。

1.3 基本语法

new关键字创建对象的语法格式如下:

类名 对象名 = new 类名();

1.4 代码案例

为了让大家更好地理解new的用法,壹哥给大家设计了如下代码案例。

/**
 * @author 一一哥Sun
 * QQ:2312119590
 * CSDN、掘金、知乎找我哦
 * 千锋教育
 */
public class Demo01 {
	public static void main(String[] args) {
		// new关键字
		Person p1 = new Person();
	}
}

在这段简单的代码中,Person p1=new Person();,前半部分Person p1,表示是在内存中分配一个Person类型的变量p1。后半部分new Person();,表示利用new关键字和构造方法来创建一个Person类型的对象,Person()是构造方法的名字。当构造方法执行完,这个Person类型的对象就建造出来了,也就为其分配了对应的内存。

虽然p1是引用类型的变量,但p1自身会存储在栈内存中。而使用new关键字创造出来的对象,则被存储在堆内存(heap)中。且在new关键字真正创建出引用类型的对象之后,会把这个对象在内存中的地址返回给p1变量进行引用,这样我们就可以通过调用p1找到对内存中的Person对象。

所以Person p1=new Person();这行代码的作用就是,把Person对象在内存中的地址 赋值 给变量p1。在Java中,我们可以把p1变量叫做引用变量,或者简称为引用。又因为p1变量中存放的是引用类型的内存地址值,我们也可以把p1的值叫做引用地址。

2. newlnstance()方法

除了使用new关键字创建对象之外,我们还可以使用newInstance()方法创建对象。该方法是java.lang.Class 或 java.lang.reflect.Constuctor类中的实例方法,其语法格式如下:

java.lang.Class Class类对象名称 = java.lang.Class.forName(要实例化的类全称);

类名 对象名 = (类名)Class类对象名称.newInstance();

我们在调用java.lang.Class类中的forName()方法时,需要将待实例化类的全限定名(如 com.yyg.Person)作为参数传递进来,然后再调用 java.lang.Class类对象的newInstance()方法创建对象。

/**
 * @author 一一哥Sun
 * QQ:2312119590
 * CSDN、掘金、知乎找我哦
 * 千锋教育
 */
public class Demo01 {
	public static void main(String[] args) {
		//newInstance()方法创建对象
		try {
			Class<?> clazz = Class.forName("com.yyg.Person");
			Person p2 = (Person) clazz.newInstance();
		} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
		}
	}
}

因为这一块的内容涉及到了反射的知识点,后面壹哥会专门讲解反射,这一块的内容大家先有所了解即可。

3. clone()方法

第三种显式创建对象的方法,就是利用实例对象的clone()方法进行对象的复制,也可以创建一个新对象出来。clone()方法创建对象时,不会调用类的构造方法,它会创建一个复制的对象,这个对象和原来的对象具有不同的内存地址,但它们的属性值却相同。

另外clone()方法是Java Object对象中被protected修饰的方法,可供子类调用以实现子类的克隆逻辑,但不能直接调用。并且我们使用该方法创建对象时,还要求待实例化的类必须实现 java.lang.Cloneable接口,否则会抛出 java.lang.CloneNotSupportedException异常,比较麻烦,所以该方法并不常用。 clone()方法创建对象的语法格式如下:

类名 对象名 = (类名)已创建好的类对象名.clone();

4. readObject()方法

我们还可以使用java.io.ObjectlnputStream对象的readObject()方法来创建一个新对象。ObjectlnputStream是IO流中的内容,以后壹哥会详细讲解Java中的IO流,大家对此先有一个大致的印象即可。

5. 小结

壹哥在上面给大家提到了4种显式创建对象的方式,在此我们进行一个小小的总结:

  • new关键字是最常用的创建对象方式;
  • 使用 new关键字 或 Class对象的newInstance()方法 创建对象时,都会调用类的构造方法;
  • 使用 Class类的newInstance()方法 创建对象时,会调用类的默认构造方法,即无参构造方法;
  • 使用 Object类的clone()方法 创建对象时,不会调用此类的构造方法,只会创建一个复制出的对象,该对象和原来的对象具有不同的内存地址,但它们的属性值相同;
  • 如果类没有实现Cloneable接口却调用它的clone()方法,会抛出 java.lang.CloneNotSupportedException异常。

三. 隐式创建

在Java中,除了可以显式地创建对象之外,还可以隐式地创建对象。隐式创建对象主要是通过以下几种方式:

  • 给String字符串变量赋值;
  • “+”号拼接多个字符串;
  • JVM虚拟机加载类时隐式创建类对象。

1. 给String字符串变量赋值

我们经常给一个字符串变量赋值,如下所示:

String str = "Hello,壹壹哥";

上面的str变量,其实就是一个String对象,该对象会由JVM虚拟机隐式地创建出来。

2. “+”号拼接多个字符串

我们知道,“+”运算符有两个基本作用:加法运算和字符串拼接。当进行字符串拼接时,其运算的结果是一个新的 String对象,示例如下:

String str1 = "Hello";
String str2 = "一一哥";
String str3 = str1+str2;    // str3引用一个新的String对象

通过上面的语句,JVM会隐式地创建出第3个String对象。

3. JVM虚拟机加载类时隐式创建类对象

当Java的JVM虚拟机加载一个类时,会隐式地创建出一个可以描述这个类的Class实例对象。类的加载是指把类的.class字节码文件读到内存中,把它存放到运行时数据区的方法区中,然后会在堆区创建一个 java.lang.Class对象,用来封装类在方法区内的数据结构。关于Java类加载机制的更多详细内容,壹哥会在高级课程阶段给大家详细讲解,敬请期待哦。

4. 小结

无论我们是釆用显式或是隐式方式创建对象,Java虚拟机都会在创建对象时包含以下步骤:

  • 给对象分配内存;
  • 将对象的实例变量自动初始化成该变量类型的默认值;
  • 初始化对象,给实例变量赋予正确的初始值。

四. 对象的使用

1. 简介

我们在通过一系列方式创建好对象之后,那么这个对象该怎么用呢?我们知道对象中有状态和行为两个核心要素,那怎么来调用一个对象的行为和状态呢?Java中,一个普通的实例对象调用它的行为和状态,基本的语法格式如下:

//调用状态

对象.属性名;

//调用方法

对象.方法名();

接下来我们通过一个小案例给大家展示一下。

2. 使用

/**
* @author 一一哥Sun
* QQ:2312119590
* CSDN、掘金、知乎找我哦
* 千锋教育
*/
public class Demo02 {
    public static void main(String[] args) {
        // 对象的使用
		//先创建一个对象
		Person p1=new Person();
		//调用对象的属性(该属性不能是私有的,否则别的类中无法看到)--状态.
		String name = p1.name;
		
		//调用对象的方法
		p1.eat();
		p1.speak("一一哥", "男", 18);
    }
}

大家要注意,当我们在A类中调用B类对象时,B类对象的属性或方法不能是私有的,否则在A类中会无法看到该属性或方法。

本节配套视频链接如下:

Bilibili External Player

五. 创建对象的内存分析(重点)

1. 内存简介

Java程序在运行时,操作系统会给程序分配三块主要的内存空间:栈内存、堆内存、方法区

  • 栈内存: 栈内存也叫做虚拟机栈,可以存放基本类型的数据和引用类型的地址,主要是局部变量。这些局部变量存放了编译期可知长度的各种基本数据类型和对象引用,方法执行完就会自动释放。栈内存具有先进后出、占用空间比较小、存取速度相对较快的特点。
  • 堆内存: 堆内存中可以存放各对象实例(所有new出来的对象都是)和数组都在堆中存放,即堆中存放的是引用类型的实际数据。堆内存占用的空间比较大,存取速度相对较慢。
  • 方法区: 方法区主要用于存储类信息、常量、静态变量,静态代码块、即时编译器(JIT Compiler)编译后的代码数据等简单言之就是存储类的结构信息。类的结构信息包括类的名称、方法信息、字段信息等。在方法区中,有一块空间叫做常量池(串池),用来存放字符串常量。还有一块空间叫做静态区,用来存储静态变量等静态数据。但在JDK 7之后,常量池、静态区作为堆中的一个子部分,方法区的概念被弱化。

2. 内存分析

/**
* @author 一一哥Sun
* QQ:2312119590
* CSDN、掘金、知乎找我哦
* 千锋教育
*/
public class Demo02 {
    public static void main(String[] args) {
        // 对象的使用
		//先创建一个Person对象
		Person p1=new Person();
        p1.name="一一哥";
        p1.age=18;
        p1.sex="男";

        //创建p2对象
        Person p2=new Person();
    }
}

在上述代码中,我们定义的Person类型p1变量实际上是一个引用,它会被存放在栈内存中,而存放实际数据的Person对象则存放在堆内存中。如下图所示:

根据上面的内存分析图可知:

  • Person类中包含了name、age、sex三个属性,它们分别是String、int、String类型。我们知道,它们的默认值分别是null、0、null。
  • 我们创建一个p1对象之后,p1会被存放在栈区,然后p1会通过堆中Person对象的内存地址,去找到该对象被实例化的内容(即name、age、sex等)。
  • Java代码中刚创建出来的对象属性都是采用默认值(null、0、null),等我们通过"对象.属性"的方式对属性进行重新赋值后,堆内存中存储的才是赋值后的内容。
  • 我们创建的另一个对象p2,p2依然在栈区,但并没有对p2进行初始化,所以p2的属性在堆内存中都是默认值。
  • 堆内存中的每一个对象,都有一个独立的内存空间。

本节内容配套视频链接如下:

Bilibili External Player

----------------------------------------------正片已结束,来根事后烟--------------------------------------------

六. 结语

至此,壹哥就给大家把Java的对象介绍完毕了,现在你知道几种创建对象的方式呢?最后再跟大家说一下,不管我们用哪种方式创建出来的对象,每个对象都是相互独立的。这些不同的对象在内存中会占有独立的内存地址,且每个对象都具有自己的生命周期。当一个对象的生命周期结束时,对象就变成了垃圾,这些垃圾对象会被JVM虚拟机自带的GC垃圾回收机制来处理。

虽然今天的代码不多,但内容很重要哦。如果你独自学习觉得有很多困难,可以加入壹哥的学习互助群,大家一起交流学习。

七. 今日作业

1. 第一题

评论区写出Java中创建对象的方式有哪些?

2. 第二题

创建一个Java对象,绘图描述出该对象创建时的内存结构。

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

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

相关文章

【Nginx高级篇】Lua基础语法和OpenResty的安装

目录 一、前言 二、Lua基础语法 hello world 保留关键字 注释 变量 字符串 空值 布尔类型 作用域 控制语句 if-else for循环 函数 赋值 返回值 Table 数组 遍历 成员函数 三、openresty的安装 &#xff08;一&#xff09;预编译安装 &#xff08;二&…

VMware中Ubuntu拓展磁盘容量的两种方式 图形化方式命令行磁盘分区方式(亲测有效简单且详细)linux磁盘分区

文章目录 前言1. 软件设置扩容2. 容量查看3. 容量拓展实现3.1 图形化容量拓展分配3.2 磁盘命令行方式拓展容量3.2.1 确定磁盘挂载目录3.2.2 系统磁盘扩容 4. 分盘扩容TIPS&#xff1a;总结&#xff1a; 前言 在用VMware虚拟机的情况下&#xff0c;一开始分配的容量在使用过程中…

PMP项目管理-[第十二章]采购管理

采购管理知识体系&#xff1a; 规划采购管理&#xff1a; 实施采购&#xff1a; 控制采购&#xff1a; 12.1 规划采购管理 定义&#xff1a;记录项目采购决策、明确采购方法、识别潜在卖方的过程 作用&#xff1a;确定是否从项目外部获取货物或服务.如果是&#xff0c;则还要确…

循环结构程序设计

一、循环结构语句 C语言提供了三种循环语句&#xff08;for语句&#xff09;、while语句和do-while语句。 for语句&#xff1a; for(表达式1 &#xff1b; 表达式2 &#xff1b; 表达式3) {   循环体语句&#xff1b; } for语句的执行过程&#xff1a; 首先计算表达式1。判断…

【LED子系统】五、核心层详解(二)

个人主页&#xff1a;董哥聊技术 我是董哥&#xff0c;高级嵌入式软件开发工程师&#xff0c;从事嵌入式Linux驱动开发和系统开发&#xff0c;曾就职于世界500强公司&#xff01; 创作理念&#xff1a;专注分享高质量嵌入式文章&#xff0c;让大家读有所得&#xff01; 文章目录…

基于B/S架构、可替代付费商业软件的一站式量化交易平台

产品简介 这是一个面向程序员的量化交易软件&#xff0c;用于期货、股票、外汇、炒币等多种交易场景&#xff0c;实现自动交易。已对接了CTP接口&#xff08;国内期货&#xff09;、老虎证券接口&#xff08;美股港股&#xff09;。 功能特性&#xff1a; 一站式平台&#x…

Protell99SE祭文

Protell99SE祭文 大概是在21年前的今天&#xff0c;我和你结合在一起&#xff0c;陪伴走过无数的设计。 我的感觉&#xff0c;大概是在2021年吧&#xff0c;你逐渐离我远去。啊&#xff0c;Protel99SE时代一去不复返了。 我用了你21年&#xff0c;虽着AD软件的到来&#xff…

【C++】19.C++11

1.C11 auto 范围for 新容器 线程库列表初始化右值引用和移动语义 lambda表达式容器支持花括号列表初始化 本质是增加一个initializer_list的构造函数initializer_list支持花括号 2.列表初始化 #define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> #include <ve…

​数字化转型升级之工业元宇宙与AIGC

月説小飞象交流会 生活就是&#xff0c;面对复杂&#xff0c;保持欢喜。心烦时&#xff0c;记住三句话&#xff1a;1、算了吧。2、没关系。3、会过去的。 内部交流│24期 数字化转型升级 工业元宇宙与AIGC data analysis ●●●● 分享人&#xff1a;李铁军 ‍ 现如今数字化不再…

定风波、渡重山、至未来:2023中国数字能源生态大会开启的新旅程

全球碳中和的时代背景下&#xff0c;面向3060发展目标&#xff0c;新使命、新技术、新应用的到来&#xff0c;都给能源产业带来了持续变革的必要性与可能性。 2023年5月11日&#xff0c;在2023中国数字能源生态大会上&#xff0c;华为数字能源技术有限公司总裁侯金龙发表了“融…

【微电网】含风、光、储联合发电的微电网优化调度研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

2023 年 IntelliJ IDEA 下载安装教程,超详细图文教程,亲测可用

. IDEA 下载 1、打开浏览器输入https://www.jetbrains.com/&#xff0c;进入 Jetbrains官网&#xff0c;点击 Developer Tools&#xff0c;再点击 Intellij IDEA 2、点击中间的 Download&#xff0c;进入IDEA下载界面 3、选择左边的 Ultimate 版本进行下载安装。Ultimate 版…

心法利器[84] | 最近面试小结

心法利器 本栏目主要和大家一起讨论近期自己学习的心得和体会&#xff0c;与大家一起成长。具体介绍&#xff1a;仓颉专项&#xff1a;飞机大炮我都会&#xff0c;利器心法我还有。 2022年新一版的文章合集已经发布&#xff0c;累计已经60w字了&#xff0c;获取方式看这里&…

让Chat-GPT成为你的微信小助理

前言 最近公司裁员风波&#xff0c;很不幸成为了裁员名单中的一员&#xff1b;此时又恰逢一波AIGC浪潮&#xff0c;首当其冲的就是GPT这样的大语言模型的诞生&#xff0c;是整个AI领域的一个质的飞跃。正好在这样一个空挡期&#xff0c;我就基于Chat-GPT 做了一些深入的实践&a…

ChatGPT是什么?

ChatGPT是什么&#xff1f; ChatGPT是一个基于人工智能技术的聊天机器人平台&#xff0c;旨在为用户提供智能化、高效率的交互体验。ChatGPT能够理解用户输入的自然语言&#xff0c;根据语义分析和机器学习算法生成相应的回答。它可以回答用户的问题、提供建议、进行闲聊等&am…

前端技术搭建井字游戏(内含源码)

The sand accumulates to form a pagoda ✨ 写在前面✨ 功能介绍✨ 页面搭建✨ 样式设置✨ 逻辑部分 ✨ 写在前面 上周我们实通过前端基础实现了飞机大战游戏&#xff0c;今天还是继续按照我们原定的节奏来带领大家完成一个井字游戏游戏&#xff0c;功能也比较简单简单&#x…

路径规划 | 图解快速随机扩展树RRT算法(附ROS C++/Python/Matlab仿真)

目录 0 专栏介绍1 什么是RRT算法&#xff1f;2 图解RRT算法原理3 算法仿真与实现3.1 ROS C实现3.2 Python实现3.3 Matlab实现 0 专栏介绍 &#x1f525;附C/Python/Matlab全套代码&#x1f525;课程设计、毕业设计、创新竞赛必备&#xff01;详细介绍全局规划(图搜索、采样法、…

〖Python网络爬虫实战㉕〗- Ajax数据爬取之Ajax 案例实战

订阅&#xff1a;新手可以订阅我的其他专栏。免费阶段订阅量1000 python项目实战 Python编程基础教程系列&#xff08;零基础小白搬砖逆袭) 说明&#xff1a;本专栏持续更新中&#xff0c;目前专栏免费订阅&#xff0c;在转为付费专栏前订阅本专栏的&#xff0c;可以免费订阅付…

Gradle下载、安装、配置

1. Gradle下载 1.1 Gradle下载地址&#xff1a;https://docs.gradle.org/current/userguide/installation.html#installing_manually 1.2 点击Download 1.3 选择想要下载的版本&#xff0c;点击binary-only即可下载 2. Gradle安装&#xff08;注意&#xff1a;安装gradle之前…

【C语言】三子棋小游戏的思路及实现(内附代码)

简单不先于复杂&#xff0c;而是在复杂之后。 目录 1. 分文件实现 2.分步骤实现 2.1 游戏菜单 2.2 创建棋盘 2.3 初始化棋盘 2.4 打印棋盘 2.5 玩家下棋 2.6 电脑下棋 2.7 判断输赢 3. 附完整代码 3.1 test.c 3.2 game.h 3.2 game.c 1. 分文件实现 当我…