this代表它所在函数所属对象的引用。简单说:哪个对象在调用this所在的函数,this就代表哪个对象。
this关键字主要有以下三个作用:
this调用本类中的属性,也就是类中的成员变量;
this调用本类中的其他方法;
this调用本类中的其他构造方法,调用时要放在构造方法的首行。(this语句只能定义在构造函数的第一行,因为在初始化时须先执行)
this关键字的基本用法
引用成员变量
public class Person{
String name; //定义成员变量name
private void SetName(String name) { //定义一个参数(局部变量)name
this.name=name; //将局部变量的值传递给成员变量
}
}
如上面这段代码中,Person类中有一个成员变量name,同时在SetName方法中有一个形式参数,名字也是name,然后在方法中将形式参数name的值传递给成员变量nam。
虽然我们可以看明白这个代码的含义,但是作为Java编译器它是怎么判断的呢?到底是将形式参数name的值传递给成员变量name,还是反过来将成员变量name的值传递给形式参数name呢?也就是说,两个变量名字如果相同的话,那么Java如何判断使用哪个变量?
此时this这个关键字就起到作用了。this这个关键字其代表的就是对象中的成员变量或者方法。也就是说,如果在某个变量前面加上一个this关键字,其指的就是这个对象的成员变量或者方法,而不是指成员方法的形式参数或者局部变量。
因此在上述代码中,this.name代表的就是对象中的成员变量,又叫做对象的属性,而后面的name则是方法的形式参数,代码this.name=name就是将形式参数的值传递给this指向对象的成员变量。
一看到这个this关键字就知道现在引用的变量是成员变量或者成员方法,而不是局部变量。这无形中就提高了代码的阅读性。
调用类的构造器方法
public class Person {
public Person(){ //无参构造器方法
this(“Hello!”);
}
public Person(String name){ //定义一个带形式参数的构造方法
}
}
在上述代码中,定义了两个构造方法,一个带参数,另一个没有带参数。在第一个没有带参数的构造方法中,使用了this(“Hello!”)这句代码,这句代码表示什么含义呢?在构造方法中使this关键字表示调用类中的构造方法。
如果一个类中有多个构造方法,因为其名字都相同,跟类名一致,那么这个this到底是调用哪个构造方法呢?其实,这跟采用其他方法引用构造方法一样,都是通过形式参数来调用构造方法的。
Tip:
语法限制:利用this关键字来调用构造方法,只有在无参数构造方法中第一句使用this调用有参数的构造方法。否则的话,翻译的时候,就会有错误信息。这跟引用成员变量不同。如果引用成员变量的话,this关键字是没有位置上的限制的。
返回对象的引用
this关键字除了可以引用变量或者成员方法之外,还有一个关键的作用就是返回对象的引用。
/**
* 资源url
*/
public HttpConfig url(String url) {
urls.set(url);
//return this就是返回当前对象的引用(就是实际调用这个方法的实例化对象)
return this;
}
调用:
HttpConfig config = HttpConfig.custom();
config = config.url(url);
return this就是返回当前对象的引用(就是实际调用这个方法的实例化对象)
this关键字和super关键字
在JAVA类中使用super来引用父类的成分,用this来引用当前对象
如果一个类从另外一个类继承,我们new这个子类的实例对象的时候,这个子类对象里面会有一个父类对象。怎么去引用里面的父类对象呢?使用super来引用,this指的是当前对象的引用,super是当前对象里面的父对象的引用
class FatherClass {
public int value;
public void f() {
value=100;
System.out.println("父类的value属性值="+value);
}
}
class ChildClass extends FatherClass {
/**
* 子类除了继承父类所具有的valu属性外,自己又独立声明了一个value属性,
*/
public int value;
/**
* 在子类ChildClass里面重写了从父类继承下来的f()方法里面的实现,即重写了f()方法的方体。
*/
public void f() {
super.f();//使用super作为父类对象的引用对象来调用父类对象里面的f()方法
value=200;//这个value是子类自己定义的那个value,不是从父类继承下来的那个value
System.out.println("子类的value属性值="+value);
System.out.println(value);//打印出来的是子类自定义的那个value的值,这个值是200
/**
* 打印出来的是父类里面的value值,由于子类在重写从父类继承下来的f()方法时,
* 第一句话“super.f();”是让父类对象的引用对象调用父类对象的f()方法,
* 即相当于是这个父类对象自己调用f()方法去改变自己的value属性的值,由0变了100。
* 所以这里打印出来的value值是100。
*/
System.out.println(super.value);
}
}
/**
- 测试类
*/
public class TestInherit {
public static void main(String[] args) {
ChildClass cc = new ChildClass();
cc.f();
}
}
属性的区别:this访问本类中的属性,如果本类没有此属性则从父类中继续查找。super访问父类中的属性。
方法的区别:this访问本类中的方法,如果本类没有此方法则从父类中继续查找。super访问父类中的方法。
构造的区别:this调用本类构造,必须放在构造方法的首行。super调用父类构造,必须放在子类构造方法首行。
其他区别:this表示当前对象。super不能表示当前对象
Tips:
在对拥有父类的子类进行初始化时,父类的构造方法也会执行,且优先于子类的构造函数执行;因为每一个子类的构造函数中的第一行都有一条默认的隐式语句super();
(如果子类的构造方法中没有手动调用父类的构造方法,则会默认调用父类的无参构造方法)
this() 和super()都只能写在构造函数的第一行;
this() 和super()
不能存在于同一个构造函数中。第一,this()和super()都必须写在构造函数的第一行;第二,this()语句调用的是当前类的另一个构造函数而这个另一个构造函数中必然有一个父类的构造器,再使用super()又调用一次父类的构造器,
就相当于调用了两次父类的构造器,编译器不会通过;
this和super不能用于static修饰的变量,方法,代码块;因为this和super都是指的是对象/实例。