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

相关推荐
魔道不误砍柴功1 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2341 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨1 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
Chrikk2 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*2 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue2 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang
杜杜的man2 小时前
【go从零单排】go语言中的指针
开发语言·后端·golang
测开小菜鸟2 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
P.H. Infinity3 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天3 小时前
java的threadlocal为何内存泄漏
java