首先我给出绝大多数视频课程以及国内教材对于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的用法暂且够了,因为我还没有找到更好的解释,等我有了更深了理解再来补充吧。