Java类与对象详解(2)

news2025/1/17 15:42:36

 

this引用

为什么要有this引用

先来看一个日期类的例子:

​
public class Date {
    public int year;
    public int month;
    public int day;

    //设置日期方法
    public void setDay(int y, int m, int d){//这里隐藏了一个Date this参数
        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(1931,9,18);
        d2.setDay(1937,7,7);
        d3.setDay(1932,1,28);

        //打印日期中的内容
        d1.printDate();
        d2.printDate();
        d3.printDate();
    }
}

​

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

但是有以下几个疑问:

1.为了提高代码的可读性,我们将setDate中的参数改为year,month,day。但这里就出现了形参名不小心与成员变量相同的问题。

public void setDay(int year, int month, int day){
        year = year;
        month = month;
        day = day;
    }

这时究竟是谁给谁传参,我们很难搞清楚。

2.三个对象都在调用setDate和printDate方法,但是这两个方法中没有任何关于对象的说明,它们是怎么知道设置,打印的是哪个对象的呢???

什么是this引用

this引用指向当前对象(成员方法运行时调用该成员方法的对象),该成员方法中所有成员变量的操作,都是通过该引用去访问。 只不过对用户隐藏了这一过程(如上文代码public void setDay(int y, int m, int d){//这里隐藏了一个Date this参数),即用户不需要传递,由编译器自动完成。

简而言之,就是谁调用了这个方法,this就是哪个对象的引用。(下图可见,对象的哈希码相同,表明使用的同一对象)。

 this引用的特性

1.this的类型:对应类类型的引用,即哪个对象调用就是哪个对象的引用类型

2.this只能在成员方法中使用

3.在成员方法中,this只能引用当前对象,不能再引用其它对象

4.this是成员方法第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用的成员方法对象的引用传递给成员方法,this负责接收

第四个特性的演示

对象的构造及其初始化 

 如何初始化对象

通过前面的知识点的学习知道,在Java方法内部定义一个局部变量时,必须要初始化,否则会编译失败。

public static void main(String[] args) {
    int a;
    System.out.println(a);
}

//Error:java:可能为初始化变量a

要让上述代码通过编译很简单,只需要在正式使用a前,给a设定一个初始值即可。如果是对象:

public static void main(String[] args) {
    Date d = new Date();
    d.printDate();
    d.setDate(1931, 9, 18);
    d.printDate();
}

//代码正常通过编译

需要调用之前的SetDate方法才可以将具体的日期设置到对象中。通过上述例子发现了两个问题:

1.每次对象创建好后调用SetDate方法设置具体日期,比较麻烦,那对象应该如何初始化?

2.局部变量必须初始化才能使用,为什么在这没有给值却能正常编译?

构造方法

概念

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

下面还是以Date来展示一下构造方法:

public class Date {
    public int year;
    public int month;
    public int day;

    //构造方法与类名相同,没有返回类型,设置为void也不行
    //一般情况下使用public修饰
    //在创建对象时由编译器自动调用,并且在对象的生命周期中只调用一次
    //带有参数的构造方法
    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
        System.out.println("Date(int, int, int)方法被调用了");
    }

    public void printDate() {
        System.out.println(year + "-" + month + "-" + day);
    }

    public static void main(String[] args) {
        //这里创建了一个Date类型的对象,并没有显式调用构造方法
        Date d = new Date(2021,6,9);//输出Date(int, int, int),表明方法被调用了
        d.printDate();
    }

}

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

特性

1.名字必须与类名相同

2.没有返回值类型,void也不行

3.创建对象时由编译器自动调用,并且在对象的生命周期只调用一次

4.构造方法允许重载,(根据自己的需求提供不同的构造方法)

构造方法重载:

public class Date {
    public int year;
    public int month;
    public int day;

    //无参的构造方法
    public class Date () {
    }
    //带有三个参数的构造方法
    public class Date (int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
}

上述两个构造方法:名字相同,参数列表不同,构成了方法重载。

5.如果用户没有显式定义,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的(注意:若用户定义了,则编译器就不会再生成了)

public class Date {
    public int year;
    public int month;
    public int day;

    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
        System.out.println("Date(int, int, int)方法被调用了");
    }

    public void printDate() {
        System.out.println(year + "-" + month + "-" + day);
    }

    public static void main(String[] args) {
        //如果编译器会生成,则生成的构造方法是无参的,则会通过编译
        //但此处未通过编译
        Date d = new Date();
        d.printDate();
    }
}
//这里没有通过编译,原因是编译器未生成构造方法,而是默认用用户的构造方法
//用户构造的和创建对象时的参数类型不匹配,所以没有通过编译

6.构造方法中,可以通过this引用调用其它构造方法来简化代码

​
public class Date {
    public int year;
    public int month;
    public int day;



    //无参的构造方法-内部给各个成员赋初值,该部分功能与三个参数的构造方法相重复
    //但是此处可以通过this调用带有三个参数的构造方法
    //this(1900,1,1);必须是构造方法的第一条语句

    public class Date () {
        //调用当前类的其它构造方法,不让自己构造自己
        this(1900,1,1);
        //this.year = 1900;
        //this.month = 1;
        //this.day = 1;
    }

    //带有三个参数的构造方法
    public class Date (int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
}

​

注意:this(...)必须是构造方法中的第一条语句

        不能形成环:

 //编译报错:递归构造器的使用

7.绝大多数情况下使用public来修饰,特殊场景下会被private修饰。

默认初始化

同上文的第二个问题:为什么局部变量在使用时必须初始化,而成员变量却不用呢

要搞清这个过程,就需要知道new 关键字背后发生的事情:

Date d = new Date(2021, 6, 9);

在程序表面可能是一条简单语句,在虚拟机层面可能要做很多事情,下面简单介绍如下:

1.检查对象对应的类是否加载了,如果没有加载的则加载

2.为对象分配空间

3.处理并发安全问题

比如:多个线程同时申请对象,JVM要保证给对象分配的空间不冲突

4.初始化所分配的空间

即:对象空间被申请好之后,对象中所包含的成员已经设置好了初始值,如下:

5.设置对象头信息

6.调用构造方法,给对象中各个成员赋值

这一期就讲到这里了哈,谢谢各位支持!!!

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

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

相关文章

广州银行信用卡中心:强化数字引擎安全,实现业务稳步增长

广州银行信用卡中心是全国城商行中仅有的两家信用卡专营机构之一,拥有从金融产品研发至销售及后期风险控制、客户服务完整业务链条,曾获“2016年度最佳创新信用卡银行”。 数字引擎驱动业务增长 安全左移降低开发风险 近年来,广州银行信用卡…

fetch的使用和实现跨域及与axios的区别

一、作用 和axios作用类似,用于请求接口。它是XMLHttpRequest的一种替代方案。 二、安装 因为fetch有兼容性问题,所以我们安装升级版 whatwg-fetch cnpm i whatwg-fetch -S 三、使用 四、fetch和axios的区别 1,fetch返回的是一个未处理…

华为OD机试真题 Java 实现【TLV格式】【2023 B卷 200分】,附详细解题思路

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题(A卷B卷&#…

聚焦 TimescaleDB VS TDengine 性能对比报告,IoT 场景下全面分析写入与查询

基于第三方基准性能测试平台 TSBS(Time Series Benchmark Suite) 标准数据集,TDengine 团队在 TSBS 的 IoT 场景中,预设了五种规模的卡车车队基础数据集,在相同的 AWS 云环境下对时序数据库(Time Series Da…

【NLP概念源和流】 01-稀疏文档表示(第 1/20 部分)

一、介绍 自然语言处理(NLP)是计算方法的应用,不仅可以从文本中提取信息,还可以在其上对不同的应用程序进行建模。所有基于语言的文本都有系统的结构或规则,通常被称为形态学,例如“跳跃”的过去时总是“跳跃”。对于人类来说,这种形态学的理解是显而易见的。 在这篇介…

【FAQ】在Linux中使用curl访问EasyCVR,返回报错Unauthorized的原因排查

EasyCVR可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安防视频监控的能力,比如:视…

【C++刷题】经典简单题第一辑

数字在升序数组中出现的次数 class Solution { public:int GetNumberOfK(vector<int>& nums, int k){size_t left 0;size_t right nums.size();size_t mid1 -1;/** 用二分法的思想寻找 k 的边界*/// 寻找 k 的左边界下标while(left < right){mid1 left (ri…

yolov3-spp 训练结果分析:网络结果可解释性、漏检误检分析

1. valid漏检误检分析 ①为了探查第二层反向找出来的目标特征在最后一层detector上的意义&#xff01;——为什么最后依然可以框出来目标&#xff0c;且mAP还不错的&#xff1f; ②如何进一步提升和改进这个数据的效果&#xff1f;可以有哪些优化数据和改进的地方&#xff1f;让…

5分钟学会你创建搜狗百科

搜狗百科属于微信生态里的平台&#xff0c;搜狗百科不仅在搜狗搜索中展示&#xff0c;且可以在微信搜索中展示。那么搜狗百科该怎么创建呢&#xff1f;下面小马识途营销顾问分享下搜狗百科词条创建的流程。 1、要创建搜狗百科词条&#xff0c;首先需要在搜狗百科官网上注册一个…

【前端入门之旅】HTML中元素和标签有什么区别?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 标签&#xff08;Tag&#xff09;⭐元素&#xff08;Element&#xff09;⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&a…

实例028 为触摸屏程序添加虚拟键盘

实例说明 由于触摸屏没有键盘&#xff0c;只能利用屏幕操作。如果要输入数据或查找数据&#xff0c;需要制作一个虚拟键盘&#xff0c;以方便用户输入。本例介绍如何实现虚拟键盘的程序设计。运行本例&#xff0c;效果如图1.28所示。 技术要点 本例中用到了Lable控件的透明属…

【HarmonyOS】性能优化之低代码开发加载多张轮播图

【关键字】 HarmonyOS、低代码开发、Swiper组件、性能优化、分页加载 写在前面 目前使用DevEco Studio的低代码工具开发元服务时&#xff0c;通过实际测试发现&#xff0c;Swiper组件加载多张轮播图时加载显示耗时较长&#xff08;实际测试网络状态一般的情况下显示耗时达到8…

好的CRM有哪些优点及功能?

市面上有很多CRM品牌&#xff0c;很多初次选型的企业没有深入的了解&#xff0c;不知道如何选择适合自己的CRM软件。小编认为&#xff0c;CRM选型无非就是靠谱和适合。这里有一款值得信赖的CRM软件推荐——Zoho CRM。 一、什么是Zoho CRM&#xff1f; Zoho CRM是一款SaaS云端…

只需十四步,从零开始掌握Python机器学习

推荐阅读&#xff08;点击标题查看&#xff09; 1、Python 数据挖掘与机器学习实践技术应用 2、R-Meta分析与【文献计量分析、贝叶斯、机器学习等】多技术融合实践与拓展 3、最新基于MATLAB 2023a的机器学习、深度学习 4、【八天】“全面助力AI科研、教学与实践技能”夏令营…

计算机视觉与图形学-神经渲染专题-第一个基于NeRF的自动驾驶仿真平台

如今&#xff0c;自动驾驶汽车可以在普通情况下平稳行驶&#xff0c;人们普遍认识到&#xff0c;真实的传感器模拟将在通过模拟解决剩余的极端情况方面发挥关键作用。为此&#xff0c;我们提出了一种基于神经辐射场&#xff08;NeRF&#xff09;的自动驾驶模拟器。与现有作品相…

无人机自动返航的关键技术有哪些

无人机的广泛应用使得无人机自动返航技术变得至关重要。在各种应对意外情况的背景下&#xff0c;无人机自动返航技术的发展对确保无人机的安全&#xff0c;以及提高其应用范围具有重要意义。接下来&#xff0c;便为大家详细介绍无人机自动返航所运用到的关键技术。 一、定位与导…

Mysql on duplicate key update用法及优缺点

在实际应用中&#xff0c;经常碰到导入数据的功能&#xff0c;当导入的数据不存在时则进行添加&#xff0c;有修改时则进行更新&#xff0c; 在刚碰到的时候&#xff0c;一般思路是将其实现分为两块&#xff0c;分别是判断增加&#xff0c;判断更新&#xff0c;后来发现在mysql…

服务器的shell脚本

shell脚本语句可以执行linux的操作语句。 linux相当于网页&#xff0c;shell相当于java。可以解释编写执行逻辑。 shell的开头以&#xff1a;#!bin/sh 定义解析方式&#xff0c;不同的linuxe内核解释方式不同。大多数内核支持sh&#xff08;bash&#xff09;方式。 执行sh文件可…

C# Onnx Paddle模型 OCR识别

RapidOCR https://github.com/RapidAI/RapidOCR/blob/main/docs/README_zh.md 效果 项目 Demo&#xff08;带模型&#xff09;下载

spring-cache框架使用笔记

spring-cache框架使用笔记 什么是spring-cache框架 spring-cache是spring框架中的一个缓存抽象层&#xff0c; 它提供了一种简便的方式来集成不同的底层缓存实现&#xff0c; 如内存缓存(concurrentMap/ehcache/caffeine)/分布式缓存(redis/couchbase)等 它简化了在app中使用…