Java this

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 (外部类实例)
        }
    }
}

编译器实现的隐藏机制

  1. 为每个内部类添加final Outer this$0字段

  2. 在构造器中自动注入外部类引用:

    java 复制代码
    // 编译器生成的构造器
    Inner(Outer outer) {
        this.this$0 = outer;  // 注入外部类引用
    }
  3. Outer.this被转换为this$0字段访问

为什么使用Outer.this而非this$0

  1. 语言安全规范:避免直接操作编译器生成字段
  2. 作用域明确性:多层嵌套时精确访问目标外部类
  3. 代码可读性:清晰表达访问意图
  4. 语法一致性:统一访问外部类成员的规范方式

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文件
内存开销 无额外对象创建 创建内部类实例
相关推荐
空影学Java10 分钟前
Day44 Java数组08 冒泡排序
java
Enddme19 分钟前
《面试必问!JavaScript 中this 全方位避坑指南 (含高频题解析)》
前端·javascript·面试
追风少年浪子彦39 分钟前
mybatis-plus实体类主键生成策略
java·数据库·spring·mybatis·mybatis-plus
橘子郡1231 小时前
深入解析Android Binder机制:从原理到实践
面试
创码小奇客1 小时前
Talos 使用全攻略:从基础到高阶,常见问题一网打尽
java·后端·架构
jackzhuoa2 小时前
java小白闯关记第一天(两个数相加)
java·算法·蓝桥杯·期末
Rover.x2 小时前
内存泄漏问题排查
java·linux·服务器·缓存
CLO_se_2 小时前
嵌入式软件面试八股文
linux·面试
midsummer_woo2 小时前
基于spring boot的纺织品企业财务管理系统(源码+论文)
java·spring boot·后端
爱分享的程序员2 小时前
前端面试专栏-前沿技术:31.Serverless与云原生开发
前端·javascript·面试