换个角度理解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的用法暂且够了,因为我还没有找到更好的解释,等我有了更深了理解再来补充吧。

相关推荐
IT毕设梦工厂7 分钟前
计算机毕业设计选题推荐-在线拍卖系统-Java/Python项目实战
java·spring boot·python·django·毕业设计·源码·课程设计
Ylucius41 分钟前
动态语言? 静态语言? ------区别何在?java,js,c,c++,python分给是静态or动态语言?
java·c语言·javascript·c++·python·学习
凡人的AI工具箱1 小时前
AI教你学Python 第11天 : 局部变量与全局变量
开发语言·人工智能·后端·python
是店小二呀1 小时前
【C++】C++ STL探索:Priority Queue与仿函数的深入解析
开发语言·c++·后端
七夜zippoe1 小时前
分布式系统实战经验
java·分布式
canonical_entropy1 小时前
金蝶云苍穹的Extension与Nop平台的Delta的区别
后端·低代码·架构
是梦终空1 小时前
JAVA毕业设计176—基于Java+Springboot+vue3的交通旅游订票管理系统(源代码+数据库)
java·spring boot·vue·毕业设计·课程设计·源代码·交通订票
落落落sss1 小时前
sharding-jdbc分库分表
android·java·开发语言·数据库·servlet·oracle
码爸1 小时前
flink doris批量sink
java·前端·flink
我叫啥都行2 小时前
计算机基础知识复习9.7
运维·服务器·网络·笔记·后端