换个角度理解this关键字(Java)

首先我给出绝大多数视频课程以及国内教材对于this的解释(样例代码都是基本一样的)

我们来看这样一段代码

java 复制代码
public class thisDemo {
    static String name;
    static int age;
    public thisDemo(String name,int age){
        name = name;
        age = age;
    }

    public static void main(String[] args) {
        thisDemo td = new thisDemo("zhangsan",12);
        System.out.println(td.name);
        System.out.println(td.age);
    }
}

这段代码的输出结果是null 0

但是很明显我们想把zhangsan赋给name,12赋给age。

但是计算机可没有这么智能,name = name是什么意思?哪个是成员变量,哪个是方法变量?

事实上,由于形式参数是方法内部的局部变量,因此当成员变量与方法中的局部变量同名时,局部变量优先,而同名的成员变量则被隐藏。

于是我们引出this关键字来解决这个问题。

java 复制代码
public class thisDemo {
    static String name;  //成员变量
    static int age;
    public thisDemo(String name,int age){   //局部变量
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {
        thisDemo td = new thisDemo("zhangsan",12);
        System.out.println(td.name);
        System.out.println(td.age);
    }
}

我认为这种说法根本不是从本质上解释this的必要性,这是对于学生的愚弄。至少这种解释是很牵强的,因为你非要让他们重名干嘛呢,写成name = dname完全可以解决这个问题,尽管这样确实会降低代码的可读性,但是总不能因为这样一个小问题就创造一个this这么抽象的概念吧。

this作为OOP中的如此常用且重要的概念,肯定不可能只用于解决一个可有可无的命名冲突问题。

因此我们再来看一个解释:

this关键字最大的作用就是让类中一个方法,访问该类里的另一个方法或者实例变量。

假设定义了一个Person类,这个Person对象的eat()方法需要调用它的move()方法,则如何做呢?是否应该定义如下的Person类呢?

Java 复制代码
public class Person {
	//定义一个move()方法
	public void move(){
		System.out.println("正在执行move()方法");
	}
	//定义一个eat()方法,eat()方法需要借助move()方法
	public void eat(){
		Person p = new Person();
		p.move();
		System.out.println("正在执行eat()方法");
	}
	public static void main(String[] args) {
		//创建Person对象
		Person p = new Person();
		//调用Person的eat()方法
		p.eat();
	}
}

运行结果为:

Java 复制代码
正在执行move()方法
正在执行eat()方法

以上这种方式确实能够做到在eat()方法里调用move()方法,但从main()方法里的程序中可以看出,一共创建了两个对象:main()方法里创建一个对象;eat()方法里创建一个对象。可是真的需要创建两个对象吗?答案是否定的!因为当程序调用eat()方法时一定会提供一个Person对象,而不需要重新创建一个Person对象了。

因此需要在eat()方法中获得调用该方法的对象,通过this关键字就可以满足这个需求。

this可以代表任何对象,当this出现在某个方法体中时,它所代表的对象是不确定的,但它的类型是确定的,它所代表的类型只能是当前类:只有当这个方法被调用时,它所代表的对象才被确定下来:谁在调用这个方法,this就代表谁。

将上面的Person类中的eat()方法改为一下这种方式更合适:

Java 复制代码
//定义一个eat()方法,eat()方法需要借助move()方法
public void eat(){
	//使用this引用调用eat()方法的对象
	this.move();
	System.out.println("正在执行eat()方法");
}

上述程序中eat()方法需要依赖于move()方法,现实中这种依赖情形非常常见,例如写字方法需要拿笔的方法,这种依赖都是同一个对象两个方法之间的依赖。因此,Java允许对象的的一个成员直接调用另一成员,可以省略this前缀。也就是说,上面的程序可以改为如下形式:

Java 复制代码
public void eat(){
	move();
	System.out.println("正在执行eat()方法");
}

上述解释从另一个角度引出了this关键字,这让我有了更深了理解,但是我仍然没有醍醐灌顶的那种透彻,不过理解到这种程度并且能够熟练运用this的用法暂且够了,因为我还没有找到更好的解释,等我有了更深了理解再来补充吧。

相关推荐
鼠爷ねずみ13 分钟前
SpringCloud前后端整体开发流程-以及技术总结文章实时更新中
java·数据库·后端·spring·spring cloud
代码or搬砖37 分钟前
String字符串
android·java·开发语言
oden1 小时前
0成本搭建!20分钟用 Workers AI + Vectorize 搞定 RAG(附全套源码)
后端
不会画画的画师2 小时前
Go开发指南:io/ioutil包应用和迁移指南
开发语言·后端·golang
AM越.2 小时前
Java设计模式详解--装饰器设计模式(含uml图)
java·设计模式·uml
5980354153 小时前
【java工具类】小数、整数转中文大写
android·java·开发语言
JIngJaneIL3 小时前
基于java + vue个人博客系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot
吃喝不愁霸王餐APP开发者3 小时前
Java后端服务在对接全国性霸王餐API时的多数据中心部署与就近调用策略
java·开发语言
从心归零3 小时前
springboot-jpa的批量更新方法
java·spring boot·spring
这周也會开心3 小时前
128陷阱,==与equals区别
java·开发语言