Object类

Object是所有类的基类(Object和object等同)。通过F12 object可以看到基类的声明如下。

namespace System
{
    public class Object
    {
        public static bool Equals(object objA,object objB){}
        public static bool ReferenceEquals(object objA,object objB){}
 
        public Object(){}
 
        public virtual bool Equals(object obj){}
        public virtual int GetHashCode(){}
        public Type GetType(){}
        public virtual string ToString(){}
 
        protected virtual void Finalize(){}
        protected object MemberwiseClone(){}
    }
}

两个不同的相等概念:值相等和引用相等。
值相等的意思是它们的数据成员按内存位分别相等。引用相等则是指它们指向同一个内存地址,或者说它们的对象句柄相等。引用相等必然推出值相等。对于值类型关系等号“==”判断两者是否值相等(结构类型和枚举类型没有定义关系等号“==”,必须自己定义)。对于引用类型关系等号“==”判断两者是否引用相等。值类型在C#里通常没有引用相等的表示,只有在非托管编程中采用取地址符“&”来间接判断二者的地址是否相等。 

静态方法Equals(object objA,object objB)
首先检查两个对象objA和objB是否都为null,如果是则返回true,否则进行objA.Equals(objB)调用并返回其值。问题归结到实例方法Equals(object obj)。该方法缺省的实现其实就是{return this= =obj;}也就是判断两个对象是否引用相等。但该方法是一个虚方法,C#推荐重写此方法来判断两个对象是否值相等。实际上Microsoft.NET框架类库内提供的许多类型都重写了该方法,如:System.String(string),System.Int32(int)等,但也有些类型并没有重写该方法如:System.Array等,在使用时一定要注意。对于引用类型,如果没有重写实例方法Equals(object obj),对它的调用相当于this= =obj,即引用相等判断。所有的值类型(隐含继承自System.ValueType类)都重写了实例方法Equals(object obj)来判断是否值相等。 

注意对于对象x,x.Equals(null)返回false,这里x显然不能为null(否则不能完成Equals()调用,系统抛出空引用错误)。从这里我们也可看出设计静态方法Equals(object objA,object objB)的原因了--如果两个对象objA和objB都可能为null,便只能用object. Equals(object objA,object objB)来判断它们是否值相等了--当然如果没有改写实例方法Equals(object obj),得到的仍是引用相等的结果。可以实现接口IComparable来强制改写实例方法Equals(object obj)。 

对于值类型,实例方法Equals(object obj)应该和关系等号“==”的返回值一致,也就是说如果重写了实例方法Equals(object obj),也应该重载或定义关系等号“==”操作符,反之亦然。虽然值类型(继承自System.ValueType类)都重写了实例方法Equals(object obj),但C#推荐重写自己的值类型的实例方法Equals(object obj),因为系统的System.ValueType类重写的很低效。对于引用类型应该重写实例方法Equals(object obj)来表达值相等,一般不应该重载关系等号“==”操作符,因为它的缺省语义是判断引用相等。 

静态方法ReferenceEquals(object objA,object objB)判断两个对象是否引用相等。如果两个对象为引用类型,那么它的语义和没有重载的关系等号“==”操作符相同。如果两个对象为值类型,那么它的返回值一定是false。 

实例方法GetHashCode()为相应的类型提供哈希(hash)码值,应用于哈希算法或哈希表中。需要注意的是如果重写了某类型的实例方法Equals(object obj),也应该重写实例方法GetHashCode()--这理所应当,两个对象的值相等,它们的哈希码也应该相等。

实例方法GetType()与typeof的语义相同,它们都通过查询对象的元数据来确定对象的运行时类型。

实例方法ToString()返回对象的字符串表达形式。如果我们没有重写该方法,系统一般将类型名作为字符串返回。 受保护的Finalize()方法在C#中作为默认的析构函数。 

受保护的MemberwiseClone()方法返回目前对象的一个“影子拷贝”,该方法不能被子类重写。“影子拷贝”仅仅是对象的一份按位拷贝,其含义是对对象内的值类型变量进行赋值拷贝,对其内的引用类型变量直接赋值引用,即拷贝后指向同一块内存。如果想做深度拷贝,需要通过实现ICloneable接口(提供Clone()方法)来完成。 

《完》

### Object 的作用 在 Java 中,`Object` 是所有的根。每个无论是否显式声明继承,都会直接或间接继承自 `Object` 。这使得 `Object` 的方法能够被所有对象使用,提供了基础功能支持。`Object` 的定义确保了所有对象都具备一些通用的行为,例如对象的比较、克隆、字符串表示等。 ### 常见方法及使用 #### 1. `toString()` 此方法返回对象的字符串表示形式。默认情况下,返回的字符串格式为 `名@哈希码`,例如 `java.lang.Object@1b6d3586`。在实际开发中,通常会重写此方法以提供更有意义的对象描述。 示例: ```java Object obj = new Object(); System.out.println(obj.toString()); // 输出:java.lang.Object@哈希码 ``` 重写示例: ```java @Override public String toString() { return "Custom String Representation"; } ``` #### 2. `equals(Object obj)` 默认情况下,`equals()` 方法用于比较两个对象的引用是否指向同一个对象实例。然而,在实际开发中,通常需要根据对象的实际属性来判断相等性,因此需要重写此方法。例如,当对象被存储在 `Map` 或 `Set` 中时,如果两个对象的 `hashCode()` 相同,则会调用 `equals()` 方法进行进一步比较。 #### 3. `hashCode()` 此方法返回对象的哈希码值。通常与 `equals()` 方法一起重写,以确保两个相等的对象具有相同的哈希码。这对于基于哈希的集合(如 `HashMap` 和 `HashSet`)的正确行为至关重要。 #### 4. `clone()` 此方法用于创建并返回对象的一个副本。要使用此功能,需要实现 `Cloneable` 接口并重写 `clone()` 方法,否则会抛出 `CloneNotSupportedException` 异常。 #### 5. `getClass()` 此方法返回运行时的 `Class` 对象,可以用于反射操作。 #### 6. `notify()` 和 `wait()` 这些方法用于线程间的协作。`wait()` 方法使当前线程等待,直到另一个线程调用 `notify()` 或 `notifyAll()` 方法。 ### Object 的重要性 由于 `Object` 是所有的超,因此它提供了一种统一的方式来处理所有对象。例如,可以通过 `Object` 型的引用变量来引用任何型的对象,从而实现多态性。 此外,`Object` 提供的方法为对象的基本操作奠定了基础。例如,`toString()` 方法使得对象可以以字符串形式输出,便于调试;`equals()` 和 `hashCode()` 方法确保了对象在集合中的正确行为;`clone()` 方法提供了对象复制的机制。 ### 示例代码 以下是一个重写 `toString()` 和 `equals()` 方法的示例: ```java public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Person{name='" + name + "', age=" + age + "}"; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; Person person = (Person) obj; if (age != person.age) return false; return name != null ? name.equals(person.name) : person.name == null; } } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值