【我与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 d3Date 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. 调用构造方法,给对象中各个成员赋值

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

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

相关文章

Flink1.17实战教程(第二篇:DataStream API)

系列文章目录 Flink1.17实战教程(第一篇:概念、部署、架构) Flink1.17实战教程(第二篇:DataStream API) Flink1.17实战教程(第三篇:时间和窗口) Flink1.17实战教程&…

Bert模型from_pretrained报网络错误解决办法

问题描述: 服务器或者本地运行以下代码时报网络连接错误: from transformers import AutoTokenizermodel_checkpoint "distilbert-base-uncased" tokenizer AutoTokenizer.from_pretrained(model_checkpoint, use_fastTrue, cache_dir./cac…

使用pytorch搭建ResNeXt并基于迁移学习训练

冻结除最后全连接层以外的所有权重,只去单独训练它最后一层的的权重,这个方法,冻结了所有网络的权重。 for param in net.parameters():param.requires_grad False

Python可视化之Matplotlib

文章目录 Matplotlib与可视化分析简单图形的绘制pylot的高级功能添加图例与注释 Matplotlib与可视化分析 我们之前对数据的处理与分析,其实最终还是要利用可视化工具进行更加直观的输出 我们开业通过 pip install matplotlib命令来安装对应的模块 简单图形的绘制…

2023年山东省高职组区块链技术竞赛任务书

2023年山东省高职组区块链技术任务书 目录 模块一:区块链产品方案设计及系统运维 任务1-1:区块链产品需求分析与方案设计 任务1-2:区块链系统部署与运维 任务1-3:区块链系统测试 模块二:智能合约开发与测试 任务2-1&am…

python 实现粒子群算法(带绘制)

本文章用python实现了粒子群算法, 标准PSO的算法流程如下: 初始化一群微粒(群体规模为m),包括随机的位置和速度;评价每个微粒的适应度;对每个微粒,将它的适应值和它经历过的最好位…

Visual Studio使用——自定义代码片段 像使用IDEA一样能快捷输入

目录 引出Visual Studio使用自定义代码片段 Idea安装和使用0.Java下载 和 IDEA工具1.首次新建项目2.隐藏文件不必要显示文件3.目录层级设置4.Settings设置选择idea的场景提示代码不区分大小写 取消git的代码作者显示 总结 引出 Visual Studio使用——自定义代码片段 & 像使…

C++ 一个有bug的贪吃蛇。。。。。。。。

C 一个有bug的贪吃蛇。。。。。。。。 #include <graphics.h> #include<Windows.h> #include<Mmsystem.h> #include<conio.h> #include<time.h> #include<stdio.h> #include<easyx.h> using namespace std; #pragma warning(di…

Google Chrome 现在会在后台扫描泄露的密码

谷歌表示&#xff0c;Chrome 安全检查功能将在后台运行&#xff0c;检查网络浏览器中保存的密码是否已被泄露。 如果桌面用户正在使用标记为危险的扩展程序&#xff08;从 Chrome Web Store 中删除&#xff09;、最新的 Chrome 版本&#xff0c;或者如果启用安全浏览来阻止 Go…

Linux系统安装字体-解决Activiti流程图无法显示问题

1、安装插件 yum install -y fontconfig mkfontscale 2、将字体复制到指定文件夹 (找到Windows系统的C:\Windows\Fonts下找微软雅黑字体【MYYH.TTC】并上传到Linux) cp MYYH.TTC /usr/share/fonts/ 3、执行安装 cd /usr/share/fonts/ mkfontscale mkfontdir 4、刷新缓存 fc-ca…

Java开发框架和中间件面试题(8)

目录 82.Mybatis一级缓存&#xff0c;二级缓存&#xff1f; 83.Mybatis如何防止SQL注入&#xff1f; 84.mybatis中resultType和resultMap有什么区别&#xff1f; 85.如何在SpringBoot中禁用Actuator断点安全性&#xff1f; 86.什么是SpringBoot&#xff1f;SpringBoot有哪些…

为什么都建议配备人员摔倒AI检测算法

旭帆科技的AI智能分析网关v4包含有30多种算法&#xff0c;包括人体、车辆、行为分析、烟火、入侵、安全帽、反光衣等等&#xff0c;可应用在安全生产、通用园区、智慧社区、智慧工地等场景中。 今天&#xff0c;小编就其中的摔倒检测算法来展开聊聊&#xff0c;可以用于哪些场…

算法训练营Day26

#Java #全排列 #回溯 开源学习资料 Feeling and experiences&#xff1a; 递增子序列&#xff1a;力扣题目链接 给你一个整数数组 nums &#xff0c;找出并返回所有该数组中不同的递增子序列&#xff0c;递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组…

GameFi 2024年或将迎来新的爆发!

在数字时代&#xff0c;游戏已经不仅仅是一种娱乐方式&#xff0c;更是一种跨越现实和虚拟界限的全球性文化现象。而游戏金融&#xff08;GameFi&#xff09;正是这场数字革命的下一个巨大风潮。 随着科技的不断发展和创新&#xff0c;2024年&#xff0c;GAMEFI&#xff08;Gam…

vitis HLS中实现canny算法的IP核

一、前言 canny边缘检测主要用于提取图像的边缘&#xff0c;是最常用且有效的边缘检测算法。在AMD赛灵思提供的库函数中&#xff0c;使用xf::cv::Canny和xf::cv::EdgeTracing两个函数实现canny边缘提取。本文举例说明如何在vitis HLS 2023.1中实现canny算法。 二、xf::cv::Cann…

《对话品牌》——活到老“养”到老

本期节目《对话品牌》栏目组邀请到了深圳壹常青健康管理有限公司董事长邬锡娣女士参加栏目录制&#xff0c;分享其企业故事&#xff0c;树立品牌形象&#xff0c;提升品牌价值&#xff01; 节目嘉宾&#xff1a;邬锡娣女士 节目主持人&#xff1a;董倩 节目播出平台&#xf…

Qt之自定义分页(翻页)控件

当数据量较大时,分页显示是个不错的选择。这里用百家姓来演示分页效果,包括首页、上一页、下一页、尾页和跳转。 一.效果 每页15个姓氏。 二.实现 QHPageWidget.h #ifndef QHPAGEWIDGET_H #define QHPAGEWIDGET_H#include <QWidget> #include <QStandardItemMod…

查询速度快 30 倍的 ClickHouse,凭什么替代 ELK?

背景 SaaS 服务未来会面临数据安全、合规等问题。公司的业务需要沉淀一套私有化部署能力&#xff0c;帮助业务提升行业竞争力。为了完善平台系统能力、我们需要沉淀一套数据体系帮助运营分析活动效果、提升运营能力。然而在实际的开发过程中&#xff0c;如果直接部署一套大数据…

059:vue中使用 AJAX来读取来自XML文件的信息

第059个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…

CVE-2017-12794_Django debug page XSS漏洞

一、影响版本 Django < 1.10.8 Django < 1.11.5 二、漏洞复现 1、vulhub搭建环境 2、首次向数据库中插入数据&#xff0c;成功插入 3、向数据库中插入相同数据&#xff0c;Django报错&#xff0c;数据被打印且执行 三、漏洞分析 查看DIFF&#xff1a; https://g…