课时9:this调用本类属性

简介: 本次分享的主题是 This 调用本类属性。主要分为一个部分:使用 This 关键字表示或调用当前对象的属性

课时9:this调用本类属性


摘要:本次分享的主题是 This 调用本类属性。主要分为一个部分:

使用 This 关键字表示或调用当前对象的属性

 

继续来探讨 Java 中一个较为棘手的概念,即名为 This 的关键字。有同学表示这次的内容较为复杂。首先要强调的是 This 可以算是Java 中较为复杂的一个关键字。这是因为 This 的使用形式决定了它的高度灵活性。


在这个程序中使用 This 关键字可以实现以下三个方面的描述。第一个称之为当前类中的属性,紧接着列出这四个属性。第二个是当前类中的方法,这里提到的方法可能包括普通方法与构造方法。使用 This 加括号调用构造方法,而使用 This 加方法名称加括号就是调用普通方法,这一点很好理解。


之后还有一个环节,把它称之为使用 This 来描述当前对象。这是一个相对灵活的概念,要讲透彻需要一些时间。从整体上看 This 最令人困惑的部分也在于此。

 

使用 This 关键字表示或调用当前对象的属性

 

下面来看一下这究竟是怎么回事。首先来看第一个概念:使用 This关键字来表示或调用当前对象的属性。


那么在讨论 This 之前,先来看一个问题。通过目前的分析可以发现利用构造方法或者是 Setter 方法都可以为对象的属性赋值,但是在进行赋值时之前可能采用的是如下的定义形式。


这个代码是这样写的。首先定义一个名为 Person 的类,在这个类中定义了两个属性:一个是 Private String Name ,另一个是Private Int Age 。通常会为这些属性提供 Setter 和 Getter 方法,但在这里为了简化省略了这些方法的具体实现。

image.png

class Person {
private String name ; 
private int age ;
// sett
}
public class JavaDemo { //主类
public static void main(String args[]){
}
}

之后通常会编写一个构造方法,接受 String 类型的 Name  Int类型的 Age 作为参数。在构造方法的实现中会将传入的 Name 赋值给类的 Name 属性,将传入的 Age 赋值给类的 Age 属性。接着可能会添加一个名为 Tell 的方法,该方法简单地输出姓名和年龄。这里只是一个简单的代码示例, Tell 方法中会输出“姓名:”加上 Name 属性的值,以及“年龄:”加上 Age 属性的值。


现在编写如下代码:创建一个 Person 类的实例 pr ,使用 New 关键字和 Person 构造方法,传入“王五”作为姓名, 38 作为年龄。然后调用 Pr  Tell 方法。代码编写完成后,很简单,也很容易理解。现在将这段 Java 代码保存为 JavaDemo.java 文件,并通过Java 编译器执行它,运行后发现没有问题,程序能够正常运行并输出结果。


而这是一个再正常不过的简单程序。相信大家一看就能轻松理解。然而有人可能会提出疑问说:“老师,我对这段话有点费解。”


image.png

class Person {
private String name ; 
private int age ;
public Person(String n,int a) {
name = n ; 
age = a ;
 }
public void tell() {
System.out.println("姓名:"+ name + "、年龄:"+ age);
}
// setter、getter略
}
public class JavaDemo { //主类
public static void main(String args[]) {
Person per = new Person("王五",38) ; 
per.tell() ;|
}

但是在构造方法的定义过程中发现一个小问题。问题出在哪里呢?出在参数的名称上。具体来说构造方法中的两个参数是为了给类的 Name  Age 绘制属性初始化。然而此时使用的参数名称比如 N A 并不直观。


最好的做法应该如何实现呢?你的目标不就是为了给变量 Name Age 赋值吗?如果直接使用 Name 作为参数名,相比使用 N  A ,前者显然更为合适且直观,我的想法是将传入的 Name 参数值赋给对象的 name 属性,但这里似乎有些混淆,那么该如何明确指定每个参数对应哪个属性呢?


按照当前的代码方式编写后,编译和执行都没有问题,但执行结果却是空的。也就是说现在代码中存在问题,只是编译时未能发现。如果尝试在构造方法中将参数名称修改为 Name  Age ,就会发现无法正确地为对象的属性设置值。在这个过程中由于参数名和属性名之间的混淆,导致属性无法被正确设置。


image.png

class Person {
private string name ;
private int age ;  
public Person (String n,int a) {
name = n;
age = a ;
 }
public void tell() {
System.out.println("姓名:"+ name + "、年龄:"+ age);
 }
// setter、getter略 
}
public class JavaDemo {//主类
public static void main(String args[]){
Person per = new Person("王五",38) ; 
per.tell() ;
}
}

image.png

D:\mldnjava>javac JavaDemo.java
D:\mldnjava>java JavaDemo
姓名:王五、年龄:38
D:\mldnjava>

那么为什么会出现这样的一种情况呢?首先大家一定要明确一件事情:在 Java 程序中,大括号是作为结构体的边界符号,那么在程序中,当使用变量时——无论是参数还是属性,都统称为变量,并且都会以大括号作为查找边界。

public Person(String name,int age){
name = name;
age= age ;
}

什么叫查找边界呢?以当前例子来讲,假设现在要写字,比如写一句“老婆你很帅”。当我要拿笔来写时,如果桌上就有笔,显然不会跑到十万八千里外去找林强借一根笔,那样可能到那里都已经老了。这是不现实的事情。


既然桌上有笔就会直接用桌上的笔来写字。现在回到这个问题上来。在构造方法中你有没有 Name 这个参数?有没有 Age 这个参数?构造方法里既有 Name 又有 Age ,那么这个时候还会去查找构造方法外面的 Name  Age 吗?


以边界为例,这个地方有没有 Name  Age参数名称呢?如果有,那还需要到构造方法外面去找这个参数吗?不需要,只需要遵循“就近取用”的原则。所以同学们,按照“就近取用”的原则,构造方法中的参数并不会直接访问到类中的属性。


为了明确区分构造方法中的参数和类中的属性,通常在引用类中的属性时,在属性名前加上一个关键字 This 所以明白这个含义了吗? This 关键字就是用来表示当前对象的属性,即“本位属性”。

image.png

class Person{
private String name;
private int age;
public Person(String name,int age) {
name = name ; 
age= age ;
}
public void tell() {
System.out.println("姓名:" + name + "、年龄:"+ age);
}
// setter、getter略 
}
public class JavaDemo { // 主类
public static void main(String args[]) {
Person per = new Person("王五",38) ; 
per.tell() ;
}
}

所以正确的代码形式应该怎么写呢?应该在构造方法中使用 This 关键字来明确区分参数和属性,比如 This.name = Name ;和 This.H = H 。这样写之后再次编译和执行程序代码,应该就能正常地为属性赋值了。这就是 This 关键字的用法。


因此要告诉大家的是在以后编写代码时,当你需要引用属性时,请确认一下它是不是属性。如果是属性那么就要在属性名前加上 This 来进行访问。


这里想告诉大家一件事情,在以后的程序开发过程中请牢记这句话:在你所编写的程序代码中,只要是访问类中的属性,特别是明确指代本类中的属性时,请一定要加上 This 关键字来实现访问。你们明白这句话的意思吗?也就是说从此以后,你们要养成一个习惯,只要访问类中的属性,就在属性名前加上 This 


这个习惯真的很重要,因为很多人在这个地方吃过亏。我最早写代码的时候,就因为有一次忘了加 This ,结果出了错,并且查了好久都没找到问题所在。那个数值就是不对劲,检查了所有地方都没问题,最后才发现就是少了个 This 


所以你们以后一定要养成这个习惯,只要是访问类中的属性,就用 This 关键字来明确访问。这样做可以确保你的代码更加清晰、准确,避免不必要的错误。

private String name ; 
private int age ;
public Person(String name,int age) {
this.name = name ; 
this.age= age ;
}
public void tell() {
System.out.println("姓名:" + this.name + "、年龄:"+this.age) ;
}
//setter、getter 略
}

相关文章
sa-token实现网关调用认证服务统一鉴权
sa-token实现网关调用认证服务统一鉴权
911 0
|
测试技术 持续交付 人机交互
软件测试计划说明书模板
软件测试计划说明书模板
701 0
|
Java
Java开发篇- 从BigDecimal的divide的异常说起
在过去做项目的某一天中,突然有小伙伴说两个BigDecimal的数据相除(divide)报错了,觉得不可能,然后问他是怎么编写的,他说很简单呀,就是new了2个BigDecimal,然后相除的结果赋值给另外一个BigDecimal对象。听起来觉得没有问题,正常来说,2个Integer(int),2个Double(double)都不会报错,然后问是什么异常,说是一个很奇怪的异常
812 0
|
监控 Java
ThreadPoolExecutor 线程执行超时,释放线程
ThreadPoolExecutor 线程执行超时,释放线程
507 1
|
Java 数据库连接 数据库
【Mybatis】mybatis 是否支持延迟加载?
【Mybatis】mybatis 是否支持延迟加载?
|
监控 算法 应用服务中间件
“四两拨千斤” —— 1.2MB 数据如何吃掉 10GB 内存
一个特殊请求引发服务器内存用量暴涨进而导致进程 OOM 的惨案。
353 14
|
存储 缓存 安全
Flutter:类功能索引(全)
本文以表描述形式收录了Flutter中提供的各个类,旨在方便地进行查询相关组件。
428 2
|
机器学习/深度学习 人工智能 自然语言处理
还不懂如何与AI高效交流?保姆级且全面的chatGPT提示词工程教程来啦!(一)基础篇
这篇文章是一篇保姆级的教程,旨在全面介绍如何与AI进行高效交流,包括ChatGPT的前世今生、应用场景以及提问的基础技巧。
还不懂如何与AI高效交流?保姆级且全面的chatGPT提示词工程教程来啦!(一)基础篇
Threejs使用CubeCamera实现环境映射
这篇文章详细介绍了如何在Three.js中使用CubeCamera来实现环境映射,包括创建CubeCamera、设置反射材质以及实时更新渲染结果的具体步骤。
475 3

热门文章

最新文章