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

相关推荐
程序员岳焱12 分钟前
Java 与 MySQL 性能优化:MySQL 慢 SQL 诊断与分析方法详解
后端·sql·mysql
爱编程的喵12 分钟前
深入理解JavaScript原型机制:从Java到JS的面向对象编程之路
java·前端·javascript
龚思凯18 分钟前
Node.js 模块导入语法变革全解析
后端·node.js
天行健的回响21 分钟前
枚举在实际开发中的使用小Tips
后端
on the way 12323 分钟前
行为型设计模式之Mediator(中介者)
java·设计模式·中介者模式
保持学习ing26 分钟前
Spring注解开发
java·深度学习·spring·框架
wuhunyu26 分钟前
基于 langchain4j 的简易 RAG
后端
techzhi26 分钟前
SeaweedFS S3 Spring Boot Starter
java·spring boot·后端
异常君1 小时前
Spring 中的 FactoryBean 与 BeanFactory:核心概念深度解析
java·spring·面试
weixin_461259411 小时前
[C]C语言日志系统宏技巧解析
java·服务器·c语言