文章首发到公众号:程序员老左,每天分享程序员职场经验及开发技术!
this ,翻译为:这、这个,在java中应该翻译为 “本对象” 或 “对象本身” ,指向的是对象自己
类似于日常的称呼,比如,别人称呼你的时候应该用姓名,比如称呼“赵云”,赵云很帅、赵云武功很强,但是赵云自己称呼自己应该用“我”,赵云:我很帅、我武功很强。而“我”就相当于this。
this 其实就是一个变量,本质上和普通的引用类型变量一样。
比如上面的称呼,无论称呼“赵云”、“我”、“你”,本质都是称呼,而且称呼的对象都是赵云。
this也是如此, 和其他该类的引用类型变量一样,本质都是变量,指向的也是同一个对象,只不过this是内置的变量而已。
为了让大家更清楚的理解,我们简单介绍下对象的创建过程,以及如何与变量关联的。
比如下面的代码:
public static void main(String[] args) {
User u = new User();
User u2 = u;
}
当main方法开始运行时,java虚拟机会为方法创建“本地变量表”,用于存储方法参数值、方法内的局部变量,比如args、u、u2。
之后运行方法内的代码,new User(), 创建User对象,虚拟机会在内存的堆中创建,比如创建的对象内存地址为:00000001 , 之后调用类构造方法初始化对象。
然后将创建的对象赋值给变量u,实际在本地变量表中,变量u存放的是对象的内存地址:00000001
之后 User u2 = u, 将u赋值给变量u2, 也就是将00000001 赋值给u2。这样,变量u、u2指向的就是同一个对象。
其实this和变量u、u2是一样的,也会存储到本地变量表中,存储的也是对象的地址。比如:
public static void main(String[] args) {
User u = new User();
User u2 = u;
u.toString();
}
public class User {
......
@Override
public String toString() {
String s = "name: " + this.name;
s += " , password: " + this.password;
return s;
}
}
当运行到u.toString()方法时,java虚拟机也会为该方法创建本地变量表,如图:
注:java虚拟机会为每个正在运行的方法都会创建一个本地变量表。
变量表中第一个位置存放的就是this,值也是对象的内存地址。由此可见,this和其他引用变量是没有本质区别的。
此时,u、u2、this指向的是同一个对象,验证一下:
User u = new User();
u.compare(u);
public void compare(User u){
if(this == u){
System.out.println("二者指向同一个对象");
}else{
System.out.println("二者指向不同对象");
}
}
调用compare方法,将变量u作为参数传入, 让其与this比较。
由于==运算符用于引用类型时,只有当引用指向的是同一个对象时才为真,运行输出:
为什么要有this?
public class User {
public String name;
public String password;
public User(){
}
public User(String name, String password){
this.name = name;
this.password = password;
}
public void print(){
String name = "admin";
System.out.println(this.name);
}
}
通过代码可以发现,当局部变量与对象属性同名时,由于局部变量的优先级高于对象属性,优先使用局部变量。
如果要访问对象属性,就必须要使用“对象.” 的方式,而this就是指向当前对象的引用。
this使用注意事项
this 的作用范围是对象内部,可以在对象方法、构造方法中使用
public User(String name, String password){
this.name = name;
this.password = password;
}
@Override
public String toString() {
String s = "name: " + this.name;
s += " , password: " + this.password;
return s;
}
也可用于给属性赋值
public class User {
public String name = "admin";
public String password = this.name;
. . .
}
this不能用于静态方法中
public static void reset(){
this.name = null;
this.password = null;
}
User.reset();
由于静态方法是属于整个类的,调用通过类名访问,不需要创建对象,方法内如果有this的话,是没办法确认这个this是指向哪个对象的。