第一部分:this关键字详解
深入理解this的6大用途和底层实现原理
学习目标
掌握this的所有用法,理解其在内存中的表示,能够正确使用this解决实际问题
1
this是什么?
核心概念
this 是当前对象的引用,指向调用方法的那个对象。每个非static方法都隐含一个this参数。
2
用法1:区分同名变量
public class Person {
private String name;
private int age;
public void setName(String name) {
this.name = name; // this.name指实例变量,name指参数
}
public void setAge(int age) {
this.age = age; // 避免参数名和实例变量冲突
}
}
3
用法2:调用当前类方法
public class Calculator {
private double result;
public Calculator add(double value) {
result += value;
return this; // 返回当前对象,支持链式调用
}
public Calculator multiply(double value) {
result *= value;
return this;
}
public double getResult() {
return this.result; // 可以省略this
}
}
// 使用示例
Calculator calc = new Calculator();
double res = calc.add(10).multiply(2).add(5).getResult(); // 结果:25.0
4
用法3:调用当前类构造器
public class Student {
private String id;
private String name;
private int age;
public Student() {
this("0000", "未知", 0); // 调用三参构造
}
public Student(String id) {
this(id, "未知", 0); // 必须放第一行
}
public Student(String id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
}
5
用法4:作为参数传递
public class Printer {
public void printPersonInfo(Person person) {
System.out.println(person.getName() + " - " + person.getAge());
}
}
public class Person {
private String name;
private int age;
public void display() {
Printer printer = new Printer();
printer.printPersonInfo(this); // 将当前对象作为参数
}
}
内存中的this
Person p1 = new Person();
p1.setName("张三");
栈内存:
p1 → [地址0x1001]
堆内存:
[地址0x1001] {
this = 0x1001
name = "张三"
age = 20
}
p1.setName("张三");
栈内存:
p1 → [地址0x1001]
堆内存:
[地址0x1001] {
this = 0x1001
name = "张三"
age = 20
}
第二部分:static修饰符
深入理解static的内存模型和使用限制
学习目标
掌握static变量、方法、代码块的特性,理解其与实例成员的区别
1
static变量(类变量)
public class University {
// 实例变量:每个对象独立
private String studentName;
private int studentId;
// 类变量:所有对象共享
public static String universityName = "清华大学";
public static int totalStudents = 0;
public University(String name, int id) {
this.studentName = name;
this.studentId = id;
totalStudents++; // 每创建一个对象,总数+1
}
public static void showUniversityInfo() {
System.out.println("大学名称:" + universityName);
System.out.println("学生总数:" + totalStudents);
}
}
2
static方法(类方法)
public class MathUtils {
// 静态工具方法
public static int max(int a, int b) {
return (a > b) ? a : b;
}
public static double circleArea(double radius) {
return Math.PI * radius * radius;
}
// 注意:静态方法不能直接访问实例成员
private int instanceVar = 10;
public static void staticMethod() {
// System.out.println(instanceVar); // 编译错误!
}
}
// 使用方式
public class TestMath {
public static void main(String[] args) {
// 无需创建对象,直接通过类名调用
int max = MathUtils.max(10, 20);
double area = MathUtils.circleArea(5.0);
}
}
3
static代码块
public class DatabaseConfig {
private static Properties config;
// 静态代码块:类加载时执行一次
static {
config = new Properties();
try {
config.load(DatabaseConfig.class.getResourceAsStream("config.properties"));
} catch (IOException e) {
throw new RuntimeException("加载配置失败", e);
}
}
public static String getProperty(String key) {
return config.getProperty(key);
}
}
实例成员
- 属于对象,每个对象一份
- 必须通过对象访问
- 可以访问实例和静态成员
- 生命周期与对象相同
Student stu = new Student();
stu.name = "张三"; // 实例变量
stu.study(); // 实例方法
静态成员
- 属于类,所有对象共享
- 可以通过类名或对象访问
- 只能访问静态成员
- 生命周期与类相同
Student.schoolName = "清华大学"; // 类变量
Student.showCount(); // 类方法
第三部分:内存模型分析
深入理解this和static的内存分布
学习目标
理解this引用和static变量在内存中的存储位置
方法区
Student.class
static变量
static方法
常量池
堆内存
Student对象1
this = 0x1001
name="张三"
this = 0x1001
name="张三"
Student对象2
this = 0x1002
name="李四"
this = 0x1002
name="李四"
栈内存
stu1 → 0x1001
stu2 → 0x1002
main方法栈帧
内存总结
- static变量:存储在方法区,类加载时分配内存
- 实例变量:存储在堆内存,对象创建时分配
- this引用:存储在堆内存的对象头中,指向对象本身
- 局部变量:存储在栈内存的栈帧中
第四部分:使用场景与模式
掌握this和static的最佳实践和设计模式
单例模式(static应用)
public class DatabaseConnection {
private static DatabaseConnection instance;
private Connection connection;
private DatabaseConnection() {
// 私有化构造器
}
public static synchronized DatabaseConnection getInstance() {
if (instance == null) {
instance = new DatabaseConnection();
}
return instance;
}
}
Builder模式(this应用)
public class Computer {
private String cpu;
private int ram;
private int storage;
public static class Builder {
private Computer computer = new Computer();
public Builder cpu(String cpu) {
computer.cpu = cpu;
return this; // 返回Builder实例
}
public Builder ram(int ram) {
computer.ram = ram;
return this;
}
public Computer build() {
return computer;
}
}
}
// 使用示例
Computer pc = new Computer.Builder()
.cpu("Intel i7")
.ram(16)
.build();
第五部分:常见错误与陷阱
总结this和static使用中的典型问题
this常见错误
错误1:在静态上下文中使用this
public static void staticMethod() {
System.out.println(this.name); // 编译错误!
}
错误2:this()调用位置错误
public Person() {
System.out.println("创建Person");
this("未知"); // 错误!必须放在第一行
}
static常见错误
错误1:静态方法访问实例变量
public class Test {
private int instanceVar = 10;
public static void method() {
System.out.println(instanceVar); // 编译错误!
}
}
错误2:静态上下文使用super
public class Child extends Parent {
public static void test() {
super.method(); // 编译错误!
}
}
第六部分:实战演练 - 学生管理系统升级
综合运用this和static构建完整系统
项目需求
- 统计创建的学生总数
- 实现学生ID自动递增
- 支持链式设置属性
- 提供静态工具方法
完整实现
public class EnhancedStudent {
// 静态变量:类级别共享
private static int nextId = 1001;
private static int totalStudents = 0;
// 实例变量:对象级别
private final int id; // 使用final确保不可变
private String name;
private int age;
private double gpa;
public EnhancedStudent() {
this("未命名", 18, 0.0); // 使用this()调用其他构造
}
public EnhancedStudent(String name, int age, double gpa) {
this.id = nextId++; // 使用静态变量生成ID
this.name = name;
this.age = age;
this.gpa = gpa;
totalStudents++; // 每创建对象,总数+1
}
// 链式设置方法(返回this)
public EnhancedStudent setName(String name) {
this.name = name;
return this;
}
public EnhancedStudent setAge(int age) {
this.age = age;
return this;
}
public EnhancedStudent setGpa(double gpa) {
this.gpa = gpa;
return this;
}
// 静态工具方法
public static int getTotalStudents() {
return totalStudents;
}
public static double calculateAverageGpa(EnhancedStudent... students) {
if (students.length == 0) return 0.0;
double sum = 0;
for (EnhancedStudent student : students) {
sum += student.gpa;
}
return sum / students.length;
}
public void display() {
System.out.printf("ID:%d 姓名:%s 年龄:%d GPA:%.2f%n", id, name, age, gpa);
}
// 静态内部类:用于构建器模式
public static class Builder {
private String name = "未命名";
private int age = 18;
private double gpa = 0.0;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder age(int age) {
this.age = age;
return this;
}
public Builder gpa(double gpa) {
this.gpa = gpa;
return this;
}
public EnhancedStudent build() {
return new EnhancedStudent(name, age, gpa);
}
}
}
// 测试类
public class TestStudentSystem {
public static void main(String[] args) {
// 使用构造器创建对象
EnhancedStudent stu1 = new EnhancedStudent("张三", 20, 3.8);
EnhancedStudent stu2 = new EnhancedStudent("李四", 19, 3.5);
// 使用链式设置
EnhancedStudent stu3 = new EnhancedStudent()
.setName("王五")
.setAge(21)
.setGpa(3.9);
// 使用Builder模式
EnhancedStudent stu4 = new EnhancedStudent.Builder()
.name("赵六")
.age(22)
.gpa(4.0)
.build();
// 显示信息
stu1.display();
stu2.display();
stu3.display();
stu4.display();
// 使用静态方法
System.out.println("学生总数:" + EnhancedStudent.getTotalStudents());
System.out.println("平均GPA:" +
EnhancedStudent.calculateAverageGpa(stu1, stu2, stu3, stu4));
}
}
ID:1001 姓名:张三 年龄:20 GPA:3.80
ID:1002 姓名:李四 年龄:19 GPA:3.50
ID:1003 姓名:王五 年龄:21 GPA:3.90
ID:1004 姓名:赵六 年龄:22 GPA:4.00
学生总数:4
平均GPA:3.80
学习总结
- this关键字:解决命名冲突、实现链式调用、调用构造器
- static变量:类级别共享数据,节省内存
- static方法:工具类方法,不依赖对象状态
- 内存理解:this在对象中,static在方法区
- 最佳实践:合理使用,避免滥用