1. this 的本质
this 是 java 中一个隐式引用变量,始终指向当前正在执行方法的对象实例。
隐式引用变量是 Java 内存管理机制自动创建的,指向当前活动对象实例的引用。它无需程序员显式声明,但始终存在于对象的方法或构造方法中,通过 this 关键字体现。
2. this 的应用
2.1 消除成员变量歧义
区分实例变量与局部变量:
java
public class UserProfile {
private String username; // 实例变量
public void setUsername(String username) {
// 使用this区分同名的实例变量和参数
this.username = username;
}
public void printInfo(String username) {
System.out.println("参数值: " + username);
System.out.println("成员变量: " + this.username);
}
public static void main(String[] args) {
UserProfile user = new UserProfile();
user.setUsername("john_doe");
user.printInfo("temp_user");
/* 输出:
参数值: temp_user
成员变量: john_doe
*/
}
}
2.2 链式调用
返回当前对象以支持连续操作:
java
public class QueryBuilder {
private String select;
private String from;
private String where;
public QueryBuilder select(String columns) {
this.select = columns;
return this; // 返回当前对象
}
public QueryBuilder from(String table) {
this.from = table;
return this;
}
public QueryBuilder where(String condition) {
this.where = condition;
return this;
}
public String build() {
return "SELECT " + select + " FROM " + from + " WHERE " + where;
}
public static void main(String[] args) {
String query = new QueryBuilder()
.select("name, email")
.from("users")
.where("age > 25")
.build();
System.out.println(query);
// 输出: SELECT name, email FROM users WHERE age > 25
}
}public class QueryBuilder {
private String select;
private String from;
private String where;
public QueryBuilder select(String columns) {
this.select = columns;
return this; // 返回当前对象
}
public QueryBuilder from(String table) {
this.from = table;
return this;
}
public QueryBuilder where(String condition) {
this.where = condition;
return this;
}
public String build() {
return "SELECT " + select + " FROM " + from + " WHERE " + where;
}
public static void main(String[] args) {
String query = new QueryBuilder()
.select("name, email")
.from("users")
.where("age > 25")
.build();
System.out.println(query);
// 输出: SELECT name, email FROM users WHERE age > 25
}
}
2.3. 构造方法互调
在同一类中调用其他构造方法:
java
public abstract class ViewGroup {
public ViewGroup(Context context) {
this(context, null);
}
public ViewGroup(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public ViewGroup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
initViewGroup();
initFromAttributes(context, attrs, defStyleAttr, defStyleRes);
}
}
2.4 对象自身传递
将当前对象作为参数传递:
java
public class Player {
private String name;
public Player(String name) {
this.name = name;
}
public void joinGame(GameSession session) {
session.addPlayer(this); // 传递当前对象
}
}
class GameSession {
private List<Player> players = new ArrayList<>();
public void addPlayer(Player player) {
players.add(player);
System.out.println(player + " 加入游戏");
}
public static void main(String[] args) {
Player p1 = new Player("Alice");
GameSession session = new GameSession();
p1.joinGame(session); // 输出: Alice 加入游戏
}
}
2.5 内部类
java
public class Outer {
private int x = 10;
class Inner {
private int x = 20;
void print() {
System.out.println(x); // 20 (内部类变量)
System.out.println(this.x); // 20 (内部类实例)
System.out.println(Outer.this.x); // 10 (外部类实例)
}
}
}
编译器实现的隐藏机制:
-
为每个内部类添加
final Outer this$0
字段 -
在构造器中自动注入外部类引用:
java// 编译器生成的构造器 Inner(Outer outer) { this.this$0 = outer; // 注入外部类引用 }
-
Outer.this
被转换为this$0
字段访问
为什么使用Outer.this
而非this$0
:
- 语言安全规范:避免直接操作编译器生成字段
- 作用域明确性:多层嵌套时精确访问目标外部类
- 代码可读性:清晰表达访问意图
- 语法一致性:统一访问外部类成员的规范方式
2.6 Lambda 表达式
Lambda 中的 this 指向包围它的类实例,而非 Lambda 自身:
java
public class LambdaThisDemo {
private String name = "Enclosing";
public void run() {
// Lambda表达式
Runnable lambda = () ->
System.out.println("Lambda this: " + this.name);
// 匿名内部类
Runnable anonymous = new Runnable() {
@Override
public void run() {
System.out.println("Anonymous this: " + this.getClass());
}
};
lambda.run(); // 输出:Lambda this: Enclosing
anonymous.run(); // 输出:类似 Outer$1.class
}
}
关键差异机制:
特性 | Lambda表达式 | 匿名内部类 |
---|---|---|
this绑定 | 外围类实例 | 内部类实例自身 |
作用域 | 继承外围类作用域 | 新建独立作用域 |
编译机制 | invokedynamic指令 | 生成新.class文件 |
内存开销 | 无额外对象创建 | 创建内部类实例 |