Object类详解

本文详细解析了Java中Object类的equals(),hashCode(),toString()以及废弃的finalize()方法,包括它们的用途、行为和重写示例,以及垃圾回收机制如何影响对象的生命周期。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

equals方法

== 和 equals的对比


== 是一个比较运算符:
  1)== :既可以判断基本类型,又可以判断引用类型;

  2)== :如果判断基本类型,判断的是值是否相等;

  3)== :如果判断引用类型,判断的是地址是否相等,即判定是不是同一个对象。

public class Equals01 {
    public static void main(String[] args) {
        A a = new A();
        A b = a;
        A c = b;
        System.out.println(a == c); // ture
        System.out.println(a == b); // ture
        
        B objB = a;
        System.out.println(objB == a); // ture
    }
}
class B{}
class A extends B{}

equals 方法:
  1)是 Object类中的方法,只能判断引用类型;

  2)默认判断的是地址是否相等,子类中往往重写该方法,用于判断内容是否相等;比如 Integer、String。

String str1 = new String("equals");
String str2 = new String("equals");
System.out.println(str1 == str2);		// false
System.out.println(str1.equals(str2));	// true


Person p1 = new Person();
p1.name = "equals";

Person p2 = new Person();
p2.name = "equals";

System.out.println(p1 == p2);	// false
// String.equals() 判断的是字符串内容是否相等
System.out.println(p1.name.equals(p2.name));	// ture
System.out.println(p1.equals(p2));	// false

hashcode 方法

  1)提高具有哈希结构的容器的效率;

  2)两个引用,如果指向的是同一个对象,则哈希值肯定是一样的!

  3)两个引用,如果指向的是不同对象,则哈希值是不一样的;

  4)哈希值主要是根据地址号来的!不能完全将哈希值等价于地址;

  5)在集合中,hashCode 如果需要的话,也会重写;

public class HashCode {
    public static void main(String[] args) {
        AA aa1 = new AA();
        AA aa2 = new AA();
        AA aa3 = aa1;

        System.out.println("aa1.hashCode() = " + aa1.hashCode());
        System.out.println("aa2.hashCode() = " + aa2.hashCode());
        System.out.println("aa3.hashCode() = " + aa3.hashCode());
    }
}
class AA{}

运行结果:
在这里插入图片描述

toString方法

基本介绍:

默认返回:全类名(包名+类名) + @ + 哈希值的十六进制;

// toString方法介绍、toString方法重写
public class ToString {
    public static void main(String[] args) {
        Monster monster = new Monster("小妖怪", "巡山的", 1000);

        // return getClass().getName() + "@" + Integer.toHexString(hashCode())
        // 1) getClass().getName()  全类名(包名+类名)
        // 2) Integer.toHexString(hashCode()) 将对象的hashCode值转成16进制字符串
        System.out.println(monster.toString());
    }
}

class Monster{
    private String name;
    private String job;
    private double sal;

    public Monster(String name, String job, double sal) {
        this.name = name;
        this.job = job;
        this.sal = sal;
    }

    // 重写 toString 方法,输出对象的属性
    // 快捷键 alt + insert -> toString
    @Override
    public String toString() {  // 重写后,一般是把对象的属性值输出
        return "Monster{" +
                "name='" + name + '\'' +
                ", job='" + job + '\'' +
                ", sal=" + sal +
                '}';
    }
}

重写前运行结果:
在这里插入图片描述
 
重写后运行结果:
在这里插入图片描述
 
当直接输出一个对象时,toString 方法会被默认的调用。

// 例子
	// 会默认调用 monster.toString() 方法
	System.out.println(monster);

 

finalize 方法 (新版被弃用)

 
finalize()

  当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法;
 
  1)当对象被回收时,系统自动调用该对象的 finalize 方法;子类可以重写该方法,做出一些释放资源的操作;

  2)什么时候被回收:当某个对象没有任何引用时,则 jvm 就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来销毁该对象,在销毁该对象前,会先调用 finalize 方法;

  3)垃圾回收机制的调用,是由系统来决定的,也可以通过 System.gc() 主动触发垃圾回收机制。

  实际开发中,几乎不会运用 finalize,更多是了解。

public class Finalize {
    public static void main(String[] args) {
        Car bwm = new Car("宝马");

        // 这时,car对象就是一个垃圾,垃圾回收器就会回收(销毁)对象;
        // 在销毁对象前,会调用该对象的 finalize 方法;
        // 程序员就可以在 finalize 中, 写自己的业务逻辑代码(比如释放资源: 数据库连接,或者打开的文件...);
        // 如果程序员不重写 finalize,那么就会调用 Object 类的 finalize,即默认处理;
        // 如果程序员重写了 finalize,就可以实现自己的逻辑。
        bwm = null;
		
		System.gc(); // 主动调用垃圾回收器
        System.out.println("");
    }
}

class Car{
    private String name;

    public Car(String name) {
        this.name = name;
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("销毁了汽车" + name);
        System.out.println("释放了一些资源...");
    }
}

运行结果:
在这里插入图片描述

<think>好的,我现在需要详细解释Python中的object。首先,我得回忆一下自己对object的理解。object是所有的基,在Python 3中,如果一个没有显式继承其他,它会默认继承object。这可能涉及到新式和旧式的区别,但Python 3已经统一使用新式,所以旧式的问题可能不用多提。 接下来,我需要确认object提供了哪些默认的方法和属性。比如__init__、__str__、__repr__这些魔术方法是否是object的一部分。可能还要提到__dict__属性,它存储对象的属性字典。另外,像__class__属性指向对象的,这些可能都是继承自object的。 然后,object的方法需要具体说明,比如__new__和__init__的作用,__del__作为析构函数。还有比较方法如__eq__、__hash__,以及__getattribute__这样的属性访问方法。可能需要举例子说明覆盖这些方法的影响。 另外,多重继承中object的位置,比如在钻石继承问题中,object作为顶级父如何影响方法解析顺序(MRO)。这部分可能需要用super()函数来说明新式的MRO处理方式。 还要提到使用dir(object)可以查看object的所有属性和方法,帮助用户探索。同时,实例化object本身的情况,比如obj = object(),但这样的实例无法添加属性,因为object没有__dict__,或者可能需要__slots__的解释。 可能需要注意用户在使用object时的一些常见误区,比如重写特殊方法时的注意事项,或者为什么自定义异常最好继承Exception而不是object。这部分需要准确,避免误导。 需要验证一些不确定的点,比如在Python 3中,所有是否确实隐式继承object。是的,Python 3中没有旧式,所以不需要显式继承。但为了代码的兼容性,可能还是建议显式写出。 最后,结构要清晰,分点讲解,可能分为概述、默认方法、重要属性、继承机制、使用示例、注意事项等部分。确保语言简洁,用例子辅助说明,比如展示如何覆盖__str__方法,或者比较两个对象的默认行为。 需要检查是否有错误,例如是否所有都继承objectobject的方法是否默认存在,以及实例化object后的限制是否正确。可能还要提到__slots__和内存优化相关的内容,但可能属于高级话题,简要提及即可。 总结下来,回答需要涵盖object的基础作用、提供的方法和属性、继承机制、使用示例以及注意事项,确保内容准确且易于理解。</think>Python中的`object`是所有的基,在面向对象编程中具有核心地位。以下是对`object`的详细解析: --- ### 一、基础概念 1. **顶级父** - 在Python 3中,所有默认隐式继承自`object`,即使不显式声明。 - 示例: ```python class MyClass: # 等价于 class MyClass(object): pass ``` 2. **新式的统一** - Python 3移除了“旧式”(Python 2中需显式继承`object`才能用新特性),所有均为新式。 --- ### 二、object提供的核心方法 `object`定义了所有的默认行为,以下为关键方法: #### 1. 生命周期方法 - `__init__(self, ...)`:构造方法(默认空实现)。 - `__new__(cls, ...)`:创建实例的静态方法(返回实例对象)。 - `__del__(self)`:析构方法(慎用,因垃圾回收机制不确定)。 #### 2. 对象表示 - `__str__(self)`:返回可读字符串(`print(obj)`时调用)。 - `__repr__(self)`:返回明确的对象描述(调试用,默认实现为名+内存地址)。 #### 3. 比较与哈希 - `__eq__(self, other)`:定义`==`行为(默认比较内存地址)。 - `__hash__(self)`:返回哈希值(若重写`__eq__`,通常需同步重写)。 #### 4. 属性访问 - `__getattribute__(self, name)`:属性访问拦截器。 - `__setattr__(self, name, value)`:设置属性时触发。 --- ### 三、重要属性 1. `__dict__` - 存储对象属性的字典(除非定义了`__slots__`)。 - 示例:`obj.__dict__['name'] = 'Alice'` 等效于 `obj.name = 'Alice'`。 2. `__class__` - 指向对象所属的(如`obj.__class__`返回`MyClass`)。 3. `__doc__` - 的文档字符串(可通过`help(obj)`查看)。 --- ### 四、继承与MRO(方法解析顺序) 1. **多继承中的角色** - `object`位于继承树的顶端,影响方法查找顺序。 - 示例: ```python class A(object): pass class B(A): pass print(B.__mro__) # 输出:(<class 'B'>, <class 'A'>, <class 'object'>) ``` 2. **super()与MRO** - 新式通过C3算法确定方法调用顺序,避免多继承的“菱形问题”。 --- ### 五、使用示例 #### 1. 重写`__str__` ```python class Person: def __init__(self, name): self.name = name def __str__(self): return f"Person: {self.name}" p = Person("Alice") print(p) # 输出:Person: Alice ``` #### 2. 禁止动态添加属性 ```python class Locked(object): __slots__ = ('name',) # 限制只能有name属性 obj = Locked() obj.name = "Alice" obj.age = 20 # 报错:AttributeError ``` --- ### 六、注意事项 1. **避免直接实例化`object`** - `obj = object()`创建的对象无法添加属性(因无`__dict__`)。 2. **特殊方法覆盖需谨慎** - 例如,重写`__eq__`时需保证逻辑一致性,否则可能破坏依赖哈希的容器(如字典、集合)。 3. **继承选择** - 自定义异常应继承`Exception`而非`object`,以兼容异常处理机制。 --- ### 七、探索object 通过`dir(object)`查看所有默认属性和方法: ```python print(dir(object)) # 输出:['__class__', '__delattr__', '__dir__', '__doc__', ...] ``` --- ### 总结 `object`是Python面向对象编程的基石,理解其默认行为和扩展机制是掌握设计的关键。通过重写其方法或利用继承机制,开发者可以灵活定制的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值