【我与Java的成长记】之this引用和构造方法的使用详解

在这里插入图片描述

系列文章目录

能看懂文字就能明白系列
C语言笔记传送门
🌟 个人主页:古德猫宁-

🌈 信念如阳光,照亮前行的每一步


文章目录

  • 系列文章目录
    • 🌈 *信念如阳光,照亮前行的每一步*
  • 前言
  • 一、this的使用
    • this引用的特性
  • 二、对象的构造和初始化
    • 成员变量和局部变量之间的差别
  • 三、如何初始化对象
    • 就地初始化
    • 通过构造方法初始化
      • 构造方法的特性
      • 构造方法的调用
  • 四、默认初始化


前言

本节目标:掌握this引用,构造方法的定义及其使用

本节重点:都是重点


一、this的使用

先看一个例子:

public class Date {
    public int year;
    public int month;
    public int day;
    public void setDay(int y, int m, int d){
        year = y;
        month = m;
        day = d;
    }
    public void printDate(){
        System.out.println(year + "/" + month + "/" + day);
    }
    public static void main(String[] args) {
// 构造三个日期类型的对象 d1 d2 d3
        Date d1 = new Date();
        Date d2 = new Date();
        Date d3 = new Date();
// 对d1,d2,d3的日期设置
        d1.setDay(2020,9,15);
        d2.setDay(2020,9,16);
        d3.setDay(2020,9,17);
// 打印日期中的内容
        d1.printDate();
        d2.printDate();
        d3.printDate();
    }
}

以上代码定义了一个日期类,然后main方法中创建了三个对象,并通过Date类中的成员方法对对象进行设置和打印,代码整体逻辑非常简单,应该没有任何问题。

但是细思之下有以下两个疑问:

  1. 形参名不小心与成员变量相同:
public void setDay(int year, int month, int day){
year = year;
month = month;
day = day;
}

这样写的话我们可能就有这些疑问了:那函数体中到底是谁给谁赋值?成员变量给成员变量?参数给参数?参数给成员变量?成员变量参数?估计自己都搞不清楚了。

  1. 三个对象都在调用setDate和printDate函数,但是这两个函数中没有任何任何有关对象的说明,setDate和printDate函数如何知道打印的是哪个对象的数据呢?
    在这里插入图片描述
    接下来有请 this登场
    this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成,在后面要习惯使用this。
public class Date {
public int year;
public int month;
public int day;
public void setDay(int year, int month, int day){
this.year = year;
this.month = month;
this.day = day;
}
public void printDate(){
System.out.println(this.year + "/" + this.month + "/" + this.day);
}
}
public static void main(String[] args) {
Date d = new Date();
d.setDay(2023,12,28);
d.printDate();
}

注意:this引用的是调用成员方法的对象
在这里插入图片描述

this引用的特性

  1. this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型
  2. this只能在成员方法中使用
  3. 在成员方法中,this只能引用当前对象,不能再引用其他对象
  4. this是成员方法第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法对象的引用传递给该成员,this来负责接收(如上图所示)

二、对象的构造和初始化

成员变量和局部变量之间的差别

在Java方法内部定义一个局部变量时,局部变量必须初始化(局部变量是声明在方法中的),否则会编译失败(C语言则可以)

例如:
在这里插入图片描述
对于上述的代码,你可以声明没有值的a,但如果想要使用时,编译器就会报错,而想要上面的代码编译通过,只需要给变量a初始化即可

如图:
在这里插入图片描述

而对于成员变量,那可就不一样了,在未初始化成员变量的时候,编译器仍然可以编译运行(注意:成员变量是声明在类内而不是方法中)
在这里插入图片描述
这是为什么呢?后面会介绍哒

三、如何初始化对象

那到底如何初始化对象呢,在Java中,初始化对象的方法有很多种,且听小弟慢慢道来

就地初始化

顾名思义,在声明变量的时候就赋予变量的值,这跟初始化局部变量一样(在实际中,就地初始化其实比较少,除非有特殊业务需求,比如任何一次对象的实例化之后,都期望这个对象叫dada,年龄为20)
在这里插入图片描述

当然我们也可以借助方法来帮助我们完成初始化
在这里插入图片描述
在这里插入图片描述

通过构造方法初始化

构造方法(也称构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且在整个对象的生命周期只调用一次(构造方法也是定义在类内)

如图是一个带两个参数的构造方法:
在这里插入图片描述
如图是一个不带参数的构造方法:
在这里插入图片描述
上述的两个构造方法,名字相同,参数列表不同,因此构成了方法重载。

特别注意的是:构造方法的作用就是对对象中的成员进行初始化,并不负责给对象开辟空间。

构造方法的特性

  1. 名字必须和类名相同
  2. 没有返回值类型,设置为void也不行
  3. 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
  4. 构造方法可以重载(用户可以根据自己的需求提供不同参数的构造方法)

重点:
如果我们没有自己定义任何一个构造方法,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的。

它长这样:
在这里插入图片描述
但是!!!!!!!
如果我们一旦写了任何一个构造方法的时候,Java就不会提供这个默认的构造方法了(救急不救穷)什么意思呢?
在这里插入图片描述
在上面的代码中,我们自己定义了一个构造方法,那么Java就不会提供一个无参的构造方法了,我们需要把参数传递给构造方法才不会报错

如图:
在这里插入图片描述

构造方法的调用

那在程序中,这些构造方法是什么时候被调用的呢?

我们用代码来检验一下
在这里插入图片描述
如图所示,只有在实例化对象的时候才被调用且在整个对象的生命周期内只调用一次。

在构造方法中,可以通过this调用其他构造方法来简化代码(注意是在构造方法中才可以)
在这里插入图片描述
在上面的代码中,可以在无参数构造方法中通过this调用带有两个参数的构造方法给成员变量初始值,特别注意的是,this(“zhangsan”,18)必须是构造 方法中的第一条语句,否则编译器会报错。

如图所示:
在这里插入图片描述

四、默认初始化

在开头我们讲述了局部变量和成员变量的差别,那为什么局部变量在使用时必须要初始化,而成员变量可以不用呢?
要搞清楚这个情况,就需要知道 new 关键字背后所发生的一些事情:

在程序层面只是简单的一条语句,在JVM层面需要做好多事情,下面简单介绍下:

  1. 检测对象对应的类是否加载了,如果没有加载则加载
  2. 为对象分配内存空间
  3. 处理并发安全问题,比如:多个线程同时申请对象,JVM要保证给对象分配的空间不冲突
  4. 初始化所分配的空间,即:对象空间被申请之后,对象中包含的成员已经设置好了初始值,比如:
数据类型默认值
byte0
char‘\u0000’
short0
int0
long0L
booleanfalse
float0.0f
double0.0
referencenull

  1. 设置对象头信息(关于对象内存模型后面会介绍)
  2. 调用构造方法,给对象中各个成员赋值

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

机器学习之人工神经网络(Artificial Neural Networks,ANN)

人工神经网络(Artificial Neural Networks,ANN)是机器学习中的一种模型,灵感来源于人脑的神经网络结构。它由神经元(或称为节点)构成的层级结构组成,每个神经元接收输入并生成输出,这些输入和输出通过权重进行连接。 人工神经网络(ANN)是一种模仿生物神经系统构建的…

动态规划08--一和零

题目描述 给你一个二进制字符串数组 strs 和两个整数 m 和 n 。 请你找出并返回 strs 的最大子集的大小,该子集中 最多 有 m 个 0 和 n 个 1 。 如果 x 的所有元素也是 y 的元素,集合 x 是集合 y 的 子集 。 思路分析 做到这道题的时候没什么思路&a…

LSTM Siamese neural network

本文中的代码在Github仓库或Gitee仓库中可找到。 Hi, 你好。我是茶桁。 大家是否还记得,在「核心基础」课程中,我们讲过CNN以及LSTM。 卷积神经网络(CNN)已经在计算机视觉处理中得到广泛应用,不过,2017年…

数字化工业中的低功耗蓝牙模块:实现智能制造的关键

在数字化工业的时代,智能制造成为推动产业升级的关键因素之一。低功耗蓝牙模块作为数字化工业的技术支持,为设备之间的高效通信和数据交换提供了理想的解决方案。本文将深入探讨低功耗蓝牙模块在数字化工业中的关键作用,以及其如何实现智能制…

德鲁伊(Druid)链接PGsql前端请求或者后端自动任务频繁出现IOException

尝试在druid配置文件中增加: socket-timeout: 60000 druid一些版本默认会给链接数据库socket默认10s,超出10s之后socket断开,对于GP数据库报的个IO异常。 (对于同样的场景mysql超出10s后提示的是socketTimeOut,所以相…

别再写一堆的 for 循环了!Java 8 中的 Stream 轻松遍历树形结构,是真的牛逼!

可能平常会遇到一些需求,比如构建菜单,构建树形结构,数据库一般就使用父id来表示,为了降低数据库的查询压力,我们可以使用Java8中的Stream流一次性把数据查出来,然后通过流式处理。 我们一起来看看&#x…

三维可视化智慧工地源码,数字孪生可视化大屏,微服务架构+Java+Spring Cloud +UniApp +MySql

源码技术说明 微服务架构JavaSpring Cloud UniApp MySql;支持多端展示(PC端、手机端、平板端);数字孪生可视化大屏,一张图掌握项目整体情况;使用轻量化模型,部署三维可视化管理,与一线生产过程相融合&#…

模糊-神经网络控制 原理与工程应用(绪论)

模糊—神经网络控制原理与工程应用 绪论 模糊和确定系统 在客观世界中,系统可分为确定性系统和模糊性系统,前者可用精确数学模型加以描述,而后者则不能。 输入输出类型 (b)的模糊性输出可通过反模糊化转换…

每周一算法:区间覆盖

问题描述 给定 N N N个闭区间 [ a i , b i ] [a_i,b_i] [ai​,bi​],以及一个线段区间 [ s , t ] [s,t] [s,t],请你选择尽量少的区间,将指定线段区间完全覆盖。 输出最少区间数,如果无法完全覆盖则输出 − 1 -1 −1。 输入格式…

【Linux】Linux服务器ssh密钥登录

ssh密码登录 ssh root地址 #需要输入密码ssh密钥登录 Linux之间密钥登录 生成公私钥 #生成公钥私钥 ssh-keygen #默认目录,默认密码空ssh-copy-id #拷贝ID到目标服务器 ssh-copy-id -i id_rsa.pub root192.168.8.22 ssh-copy-id -i id_rsa.pub root192.168.8.33…

安卓无法下载gradle或者下载gradle只有几十k的时候怎么办

简单说明:检查项目根目录的build.gradle文件,新版本的检查setting.gradle文件,看看repositories中有没有mavenCentral(),没有的话,加上,放在前面,把阿里的镜像也放上maven { url ‘https://mave…

linux ARM64 异常

linux 的系统调用是通过指令陷入不同异常级别实现的。arm64 架构的 cpu 的异常级别结构如下: 在上图中,用户层运行在 EL0 也就是异常级别 0,Linux 内核运行在 EL1 也就是异常级别 1,安全可信操 作系统运行在异常级别 2&#xff1a…

k8s的二进制部署和网络类型

k8s的二进制部署 master01:192.168.233.10 kube-apiserver kube-controller-manager kube-scheduler etcd master02:192.168.233.20 kube-apiserver kube-controller-manager kube-scheduler node01:192.168.233.30 kubelet kube-proxy etc…

【数据结构】C语言实现单链表的基本操作

单链表基本操作的实现 导言一、查找操作1.1 按位查找1.1.1 按位查找的C语言实现1.1.2 按位查找的时间复杂度 1.2 按值查找1.2.1 按值查找的C语言实现1.2.2 按值查找的时间复杂度 二、插入操作2.1 后插操作2.2 前插操作 三、删除操作结语 导言 大家好,很高兴又和大家…

10 分钟了解 nextTick ,并实现简易版的 nextTick

前言 在 Vue.js 中,有一个特殊的方法 nextTick,它在 DOM 更新后执行一段代码,起到等待 DOM 绘制完成的作用。本文会详细介绍 nextTick 的原理和使用方法,并实现一个简易版的 nextTick,加深对它的理解。 一. 什么是 n…

深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第一节 理解堆与栈

深入浅出图解C#堆与栈 C# HeapingVS Stacking第一节 理解堆与栈 [深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第一节 理解堆与栈](https://mp.csdn.net/mdeditor/101021023)[深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第二节 栈基本工作原理](https://mp.csdn.n…

Python 小程序之动态二位数组

动态二位数组 文章目录 动态二位数组前言一、基本内容二、代码编写三、效果展示 前言 没想出啥好点子,这次就给大家写个小程序,动态二维数组吧。 一、基本内容 程序画一个二维的方格,然后里面填上1-10的随机数,每隔一秒更新新一…

网工内推 | 网络服务工程师,HCIE认证优先,带薪年假,年终奖

01 高凌信息 招聘岗位:服务工程师(珠海) 职责描述: 1、负责华为数通(交换机、路由器)、IT(服务器、存储)等任一或多个产品领域的项目实施交付; 2、独立完成华为数通&…

【信息安全原理】——拒绝服务攻击及防御(学习笔记)

📖 前言:拒绝服务攻击(Denial of Service, DoS)是一种应用广泛、难以防范、严重威胁网络安全(破坏可用性)的攻击方式。本章主要介绍DoS的基本概念、攻击原理及防御措施。 目录 🕒 1. 定义&#…

Python面向对象高级与Python的异常、模块以及包管理

Python面向对象高级与Python的异常、模块以及包管理 一、Python中的继承 1、什么是继承 我们接下来来聊聊Python代码中的“继承”:类是用来描述现实世界中同一组事务的共有特性的抽象模型,但是类也有上下级和范围之分,比如:生物 => 动物 => 哺乳动物 => 灵长型…