类的基础语法(笔记补充)
一、构造器(Constructor):对象的“出生证明”
定义
构造器是类中一种特殊的方法,专门用于对象的初始化。当使用 new
关键字创建对象时,JVM 会自动调用构造器,为对象分配内存并设置初始状态。
核心特性
-
命名规则:必须与类名完全一致(包括大小写),且无返回值类型(不能写
void
)。public class Book {public Book() {} // 正确:构造器名与类名一致public void Book() {} // 错误:误写返回值,变成普通方法 }
-
默认构造器:若类中未显式定义构造器,编译器会自动生成无参构造器;若显式定义了构造器,默认构造器会被覆盖,需手动添加(否则
new 类名()
报错)。 -
构造器重载:允许定义多个构造器(通过参数列表区分),满足不同初始化需求。
public class Student {private String name;private int age;public Student() {} // 无参构造器public Student(String name) { this.name = name; } // 单参构造器public Student(String name, int age) { // 双参构造器this.name = name;this.age = age;} }
-
构造器间调用:通过
this(参数)
在一个构造器中调用另一个构造器(必须放在第一行,减少代码冗余)。
注意事项
- 框架(如 Spring、MyBatis)常通过反射调用无参构造器,实体类必须保留无参构造器。
- 私有构造器(
private
)可防止类被外部实例化(如工具类Math
)。
易错点
- 忘记显式定义无参构造器:只写有参构造器时,
new Student()
会编译报错。 - 构造器递归调用:构造器 A 调用 B,B 又调用 A,导致栈溢出。
二、this 关键字:对象的“自我引用”
定义
this
代表当前对象的引用(正在执行方法的对象),仅能在非静态方法或构造器中使用。
核心用法
-
区分成员变量与局部变量:当参数/局部变量与成员变量同名时,用
this.成员变量
明确指向成员变量。public class Car {private String color;public void setColor(String color) {this.color = color; // this.color 指成员变量,color 指参数} }
-
调用本类其他构造器:通过
this(参数)
复用构造器逻辑(必须在构造器第一行)。 -
作为方法返回值:返回当前对象,支持链式调用(如
builder
模式)。public User setName(String name) {this.name = name;return this; } // 链式调用:new User().setName("张三").setAge(20);
-
作为参数传递:将当前对象传给其他方法,实现对象间交互。
注意事项
static
环境中不能使用this
(static
属于类,不依赖对象)。this
始终指向当前对象,不可能为null
。
三、封装(Encapsulation):对象的“隐私保护”
定义
封装是 OOP 三大特性之一,指将对象的状态(成员变量)隐藏,仅通过公共方法对外暴露可控操作,实现数据安全与低耦合。
实现方式(三步法)
- 用
private
修饰成员变量(仅本类可访问)。 - 提供
public
的getter
(获取值)和setter
(修改值)方法。 - 在
setter
中添加校验逻辑(如范围检查、非空判断)。
示例:
public class Person {private String name;private int age;public String getName() { return name; }public void setName(String name) {if (name == null || name.isEmpty()) {throw new IllegalArgumentException("姓名不能为空");}this.name = name;}public int getAge() { return age; }public void setAge(int age) {if (age < 0 || age > 150) {throw new IllegalArgumentException("年龄必须在0-150之间");}this.age = age;}
}
访问修饰符与封装粒度
修饰符 | 本类 | 同包 | 子类 | 任意类 | 适用场景 |
---|---|---|---|---|---|
private | ✅ | ❌ | ❌ | ❌ | 成员变量(严格隐藏) |
默认(无) | ✅ | ✅ | ❌ | ❌ | 同包内可见(包内封装) |
protected | ✅ | ✅ | ✅ | ❌ | 允许子类访问(继承场景) |
public | ✅ | ✅ | ✅ | ✅ | 公共接口(完全开放) |
易错点
- 直接暴露成员变量:用
public
修饰变量(如public int age
),导致外部可随意赋值无效数据。 setter
缺失校验逻辑:如允许年龄为负数,破坏数据合法性。
四、实体类(Entity Class):数据的“载体”
定义
实体类(POJO/JavaBean)是专门存储数据的类,对应现实实体(如用户、订单),是数据在程序中的“载体”。
核心规范
- 成员变量私有:用
private
修饰,通过getter
/setter
访问。 - 必须有无参构造器:框架反射创建对象时需要。
- 完整的 getter/setter:遵循命名规范(布尔类型用
isXxx()
)。 - 重写核心方法:
toString()
(方便打印)、equals()
和hashCode()
(对象比较)。 - 实现
Serializable
:支持序列化(网络传输/持久化)。
示例(User 实体类)
import java.io.Serializable;
import java.util.Objects;public class User implements Serializable {private static final long serialVersionUID = 1L; // 序列化版本号private Long id;private String username;private boolean isVip;public User() {} // 无参构造器public User(Long id, String username) { // 有参构造器this.id = id;this.username = username;}// getter/setter(布尔类型用 isVip())public Long getId() { return id; }public void setId(Long id) { this.id = id; }public boolean isVip() { return isVip; }public void setVip(boolean vip) { isVip = vip; }@Overridepublic String toString() {return "User{id=" + id + ", username='" + username + "'}";}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;User user = (User) o;return Objects.equals(id, user.id);}@Overridepublic int hashCode() {return Objects.hash(id);}
}
易错点
- 缺少无参构造器:框架反射创建对象时抛出
InstantiationException
。 getter
命名错误:布尔变量isVip
的 getter 写成getIsVip()
(正确为isVip()
)。
五、static 静态变量:属于类的“共享资源”
定义
static
修饰的变量称为静态变量(类变量),属于类本身,所有对象共享同一副本,存储在方法区(类加载时初始化)。
核心特性
- 生命周期:与类一致(类加载时创建,类卸载时销毁)。
- 访问方式:推荐
类名.静态变量
(无需创建对象),也可通过对象访问(不推荐)。 - 唯一性:内存中仅一份,修改一个对象的静态变量,所有对象都会受影响。
用法示例(共享计数器)
public class Product {private static int totalCount = 0; // 静态变量:所有商品共享private String name; // 后续会讲的实例变量public Product(String name) {this.name = name;totalCount++; // 每创建一个商品,计数器+1}public static int getTotalCount() { // 静态方法return totalCount;}public static void main(String[] args) {new Product("手机");new Product("电脑");System.out.println(Product.getTotalCount()); // 输出 2}
}
实战场景
- 常量定义:
public static final double PI = 3.1415926;
(全局共享的不变值)。 - 工具类配置:如日志工具的静态级别配置。
易错点
- 误认为静态变量属于对象:修改一个对象的静态变量(如
p1.count=10
),会影响所有对象。 - 多线程安全问题:多个线程同时修改静态变量可能导致数据不一致,需加锁保护。
六、static 静态方法:类级别的“工具函数”
定义
static
修饰的方法称为静态方法(类方法),属于类本身,不依赖对象即可调用。
核心特性
- 调用方式:
类名.静态方法
(无需创建对象)。 - 访问限制:只能访问静态成员(静态变量/静态方法),不能访问非静态成员或使用
this
/super
。
用法示例(工具方法)
public class StringUtils {private StringUtils() {} // 私有构造器:防止创建对象// 静态方法:判断字符串是否为空public static boolean isEmpty(String str) {return str == null || str.trim().isEmpty();}
}
注意事项
- 静态方法不能被重写(Override):子类可定义同名静态方法(称为“隐藏”),但不遵循多态。
- 工具类通常全部方法为静态方法(如
java.util.Arrays
)。
七、实例变量(Instance Variable):对象的“个性特征”
定义
实例变量(非静态成员变量)是类中未被 static
修饰的变量,属于对象个体。每个对象有独立副本,其值仅影响当前对象。
核心特性
- 属于对象:随对象创建而初始化(存储在堆内存),随对象销毁而回收。
- 独立副本:每个对象的实例变量互不干扰(修改 A 不影响 B)。
- 访问方式:必须通过对象访问(
对象.实例变量
)。 - 默认值:未赋值时会被赋予默认值(如
int
为 0,String
为null
)。
与静态变量的核心区别
维度 | 实例变量(非静态) | 静态变量(类变量) |
---|---|---|
所属主体 | 属于对象 | 属于类 |
内存存储 | 每个对象一份副本(堆内存) | 类加载时创建,仅一份(方法区) |
访问方式 | 必须通过对象(对象.变量 ) | 推荐通过类名(类名.变量 ) |
生命周期 | 与对象一致(创建→销毁) | 与类一致(加载→卸载) |
适用场景 | 描述对象的个性化特征(如姓名) | 描述类的共享特征(如总数量) |
用法示例
public class Dog {// 实例变量:每个狗对象独有的属性private String name; private int age;public Dog(String name, int age) {this.name = name;this.age = age;}public static void main(String[] args) {Dog dog1 = new Dog("旺财", 3);Dog dog2 = new Dog("小白", 2);dog1.age = 4; // 修改 dog1 的实例变量System.out.println(dog1.age); // 4(仅影响 dog1)System.out.println(dog2.age); // 2(无变化)}
}
易错点
- 在静态方法中直接访问实例变量:静态方法属于类,需通过对象访问(如
new Dog().name
)。 - 默认值陷阱:未赋值的实例变量使用默认值(如
int
为 0),若 0 是有效业务数据可能出错。
总结:核心概念关联与记忆口诀
概念 | 核心作用 | 关键关联点 |
---|---|---|
构造器 | 初始化对象(含实例变量) | 配合 this 实现重载,为实例变量赋初值 |
this | 指代当前对象 | 区分实例变量与局部变量,调用构造器 |
封装 | 保护成员变量,控制访问 | 实体类的基础(私有变量+公共方法) |
实体类 | 存储数据 | 以实例变量为核心,遵循规范便于框架使用 |
静态变量 | 提供类级共享资源 | 与实例变量对立(共享 vs 独有) |
静态方法 | 提供类级工具函数 | 仅能访问静态成员,不能直接操作实例变量 |
实例变量 | 存储对象的个性化状态 | 封装的核心保护对象,构造器的初始化目标 |
记忆口诀:
- 构造器:类名相同无返回,对象创建必调用,默认无参要记牢。
this
:当前对象的引用,区分变量调构造,静态环境不能用。- 封装:私有变量公共方法,数据安全耦合低,访问修饰控粒度。
- 实体类:私有属性 get/set,无参构造序列化,三法重写(toString/equals/hashCode)很重要。
- 静态成员:属于类而非对象,共享资源工具用,静态非静不互通。
- 实例变量:对象独有存堆中,默认值要留心,静态方法不能直接用。