Java对象是「状态+行为+身份」三者绑定的运行时实体,而非内存地址或模板实例;其身份由JVM管理,==比较身份,equals默认也比身份,重写后可比状态。
Java 中的对象不是内存地址,也不是模板实例,而是「状态 + 行为 + 身份」三者绑定的运行时实体。
很多人初学时把 new Person() 理解为“复制一个模板”,这是错的。类只是描述,对象才是真实存在的个体——它有自己的一份字段值(状态),能执行自己的方法(行为),且在 JVM 中拥有唯一标识(System.identityHashCode() 可反映其身份)。
关键点:
== 比较的是身份(底层是引用指向的堆地址),不是内容;equals() 默认行为也是比较身份,重写后才可能比较状态;name、age 等字段副本。虽然对象确实分配在堆上,但仅从内存角度理解会丢失 OOP 的设计意图。例如:
BankAccount 对象不只是存着 balance 字段的内存,它还隐含“不允许透支”“余额变动需记日志”等约束逻辑;account.withdraw(100) 不是“改一个数”,而是触发一整套受控的状态变迁;当多个线程共享一个 ArrayList 实例,或 Hibernate 把一个 User 对象映射到数据库时,“是不是同一个对象”直接影响行为:
list 实例,add() 会竞争同一把锁(若同步);换成两个不同 ArrayList 实例,则完全隔离;session.get(User
.class, 1) 返回的是同一个 Java 对象引用,而非两个新对象;readObject() 恢复的是新对象,原身份丢失——这也是为什么 == 在反序列化后几乎总为 false。真正容易被忽略的是:对象的身份不可见、不可复制、不可预测,只在运行期由 JVM 统一管理。写代码时依赖 equals() 和 hashCode() 契约,而不是假设“new 出来的就一定不同”或“字段一样就该相等”。