this是Java的关键字之一,指向调用该方法的对象。this的用处主要有两种情况:
this关键字出现在成员方法中;
this关键字出现在构造方法中。
这里分别讨论,既然说了this指代的是当前调用该方法的对象,那么,有什么用呢?看下面的代码:
class Test {
public int i = 10;
public void fun01() {
System.out.println("i="+i);
}
public void fun02() {
i++;
Test test = new Test();
test.fun01();
}
}
public class Test02{
public static void main(String[] args) {
Test test = new Test();
test.fun01(); //10
test.fun02(); //10
}
}
在上面的代码中,我的目的是在Test02中新建一个Test类型的对象,然后分别调用fun01与fun02方法,在调用完fun01方法(功能是打印)以后,在fun02里面让i增加1,然后再输出一遍增加后的i,因为我们说static修饰的方法用类调用,没有static修饰的方法要用对象调用,所以创建了一个Test类型的对象,调用方法fun1,本来预期是输出10以后输出11,但是结果输出了两个10,为什么会是这样呢?
这里的原因是:我们出现了两个new Test();语句,上一更新也说过,new关键字是用来给对象开辟空间的,说明在上面的程序里面有两个对象,我们在fun02中使用的不是我们在Test02中新创建的,两个对象的地址不一样,里面的属性值肯定也不一样,那么怎么解决呢?在创建类的时候,没有创建对象啊,怎么确定是哪一个对象在引用这个方法呢?
这就是this的用处了,this用来指代当前正在调用该方法的对象,这样,就解决了我们的问题,修改代码:
class Test {
public int i = 10;
public void fun01() {
System.out.println("i="+i);
}
public void fun02() {
i++;
this.fun01();
}
}
public class Test02{
public static void main(String[] args) {
Test test = new Test();
test.fun01(); //10
test.fun02(); //11
}
}
这样,就问题解决,达到了我们预期的目的,这样分析一下,其实this关键字就是一个假设,假设是这个对象在调用我这个方法。
简单的理解了this关键字以后,看看this关键字使用的几种情况:
在成员方法中,调用成员方法与成员属性,
class Test {
public int i = 10;
public void fun01() {
//调用成员属性
this.i++;
//调用成员方法
this.fun01();
}
}
就是这么简单,有可能会注意到前面的i我没有加this,这是因为this关键字是可以省略不写的,而且大多数时候都是省略不写的,在什么情况下不能省略呢?最常见的是下面这种情况:
class Test {
public int i = 10;
public void fun01() {
int i = 20;
System.out.println(i);//20
System.out.println(this.i);//10
}
}
public class Test02{
public static void main(String[] args) {
Test test = new Test();
test.fun01();
}
}
当我们的方法里面 出现了局部变量与成员变量命名冲突的时候,上面的代码,Test类里面有一个全局变量i,而在fun01方法里面也有一个局部变量i,如果这时候不加以区分,两个变量会混淆,所以在调用全局变量的时候再全局变量前this.来加以区分。
在构造方法中,成员方法的用法也适用,只是有一种特殊的用法,就是当构造方法重载的时候,调用别的构造方法,当然这个会在接触到方法重载以后详细的理解,这里只需要记住就好:
class Test {
public Test() {
}
public Test(int i){
this();
}
}
上面的两个构造器,有参的构造器又调用了无参的构造器。
还有一个注意点,我们前面说this可以出现在成员方法与构造方法中,那么可以出现在static修饰的静态方法中呢?
答案是不可以的,this不能出现在静态方法中,其中的原因我们分析一下:
this是用来指代一个将要调用这个方法的对象;
static修饰的方法属于类,不属于对象;
所以,用一个指代对象的关键词引用不属于对象的方法,肯定是不可以的。
当然,这样只是帮助理解一下,要是严谨一点还是因为类与对象的内存加载时间与生命周期不一样的原因,更深入的了解会在后面更新Java的内存机制。