zoukankan      html  css  js  c++  java
  • System.Object简介

    Object中的公共方法解释:
    公共方法:
    Equals:
    public class Object {
    public virtual Boolean Equals(Object obj)
    {
    //如果两个引用指向同一个对象,他们肯定包含相同的值
    if (this == obj) return true;
    return false;
    }
    }
    假设this和obj实例引用同一个对象,就返回true。似乎合理是因为Equals知道对象肯定包含和他自身一样的值。但假如实例引用不同对象,Equals就不肯定对象是否包含相同的值,所以就返回false。换言之,对于Object的Equals方法的默认实现,他是实现的实际是同一性,而非相等性。
    Equals方法的正确实现:
    1,如果obj实参为null,就返回false,因为调用非静态的Equals方法时,this所标识的当前对象显然不能为null
    2,如果this和obj实参引用同一个对象,就返回true。在比较包含大量字段的对象时,这一步有助于提升性能
    3,如果this和obj实参引用不同类型的对象,就返回false。一个string对象显然不等于一个FileStream对象
    4,针对类型定义的每个字段,将this对象中的值与obj对象中的值进行比较,任何字段不相等,就返回false
    5,调用基类的Equals方法来比较他的定义的任何字段,如果基类的Equals方法方法返回false,就返回false,否则就返回true
    注:
    同一性问题的测试使用Object的静态方法ReferenceEquals,其原型如下:
    public static Boolean ReferenceEquals(Object objA, object objB)
    {
    return (objA==objB);
    }
    检查同一性问题(看两个引用是否指向同一个对象)务必调用ReferenceEquals,不应该使用C#的==操作符(除非先把两个操作数都转型为Object),因为某个操作数的类型可能重载了==符,为其赋值不同于同一性的语义。
    System。ValueType(所有值类型 基类)都重写了Object的Equals方法,并进行了正确的实现来执行值的相等性检查(而不是同一性检查),ValueType的Equals内部实现如下:
    1,如果obj实参为null,就返回false
    2,如果this和obj实参引用不同类型的对象,就返回false
    3,针对类型定义的每个实例字段,都将this对象中的值与obj对象中的值进行比较(而不是同一性检查)。ValueType的Equals内部的实现方式如下:
    1,如果obj实参为null,就返回false
    2,如果this和obj实参引用不同类型的对象,就返回false
    3,针对类型定义的每个实例字段,都将this对象中的值与obj对象中的值进行比较(通过调用字段的equals方法),任何字段不相等,就返回false
    4,返回true。ValueType的Equals方法不调用Object的Equals方法
    在内部,ValueType的Equals方法利用反射完成上述步骤3,由于CLR反射机制慢,定义自己的值类型时应重写Equals方法来提供自己的实现,从而提高自己类型的实力进行相等性比较的性能,当然,自己的实现不调用base.Equals.
    注:
    定义自己的类型时,重写的Equals要符合相等性的4个特征
    1,Equalse必须自反:x.Equals(x)肯定返回true
    2,Equals必须对称:x.Equals(y)和y.Equals(x)返回值相同
    3,Equals必须可传递:x.Equals(y)返回true,y.Equals(z)返回true,则x.Equals(z)肯定返回true
    4,Equals必须一致。比较两个值不变,Equals返回值也不变
     
    GetHashCode:
    当你定义的类重写了Equals方法,还必须重写GetHashCode方法。之所以这样要求,是由于System.Collections.Hashtable类型,System.Collection.Generic.Dictionary类型以及其他一些集合的实现中,要求两个对象必须具有相同的哈希码才视为相等。所以重写Equals就必须重写GetHashCode确保相等性算法和对象哈希码算法一致性。简单点说就是,向集合中添加键/值对,首先要获取对象的哈希码。该哈希码指出键/值对要存储到那个哈希桶中。集合需要查找键时,会获取指定键对象的哈希码,该哈希码标识了现在要以顺序方式搜索的哈希桶,将在其中查找与指定键对象相等的键对象。采用这个算法来存储和查找键,意味着一旦修改了集合总的一个键对象,集合就再也找不到该对象。所以,需要修改哈希表中的键对象时,正确的做法是移除原来的键/值对,修改键对象,再将新的键/值对添加回哈希表。
    自定义GetHashCode方法或许不是一件难事,但是取决已数据类型和数据的分布情况。下面会给出一个例子和规则:
    internal sealed class Point
    {
    private readonly Int32 m_x, m_y;
    public override int GetHashCode()
    {
    return m_x ^ m_y; //返回m_x和m_y的XOR结果
    }
    }
    规则:
    1,这个算法要提供良好的随机分布,使哈希表获得最佳性能
    2,可在算法中调用积累的GetHashCode方法,并包含他的返回值。但一般不要调用Object或ValueType的GetHashCode方法,因为两者的实现都与高性能哈希算法不沾边
    3,算法执行速度尽量快
    4,包含相同值的不同对象应返回相同哈希值。例如,包含相同文本的两个string对象返回相同的哈希码
    5, System.Object实现的GetHashCode方法对派生类型和其他的字段一无所知,所以返回一个在对象生存期保证不变的编号。
    ToString:
    默认返回类型的完整名称(this.GetType().FullName)
    GetType:
    返回从Type派生的一个类型的实例,指出调用GetType的那个对象时什么类型。返回的Type对象可以和反射类配合,获取与对象的类型有关的元数据信息。另外GetType是非虚方法,目的是防止类重写该fangfa,隐瞒企类型,进而破坏类型安全。
     
    受保护方法:
    MemberwiseClone:
    这个非虚方法创建类的新实例,并阿静对象的实例字段设与this对象的实例字段完全一致。返回对新实例的引用。
    Finalize:
    在垃圾回收器判断对象作为垃圾被回收之后,在对象的内存被实际回收之前,会调用这个虚方法。需要在回收前执行清理工作的类型应重写该方法。
  • 相关阅读:
    软件设计师-成绩查询
    spring data jpa
    Maven 项目中使用 logback
    spring boot 整合 Camunda
    Spring 中 bean 的生命周期?
    如何合理的使用工具提高效率?
    Java 中的日志
    HashMap 原理?jdk1.7 与 1.8区别
    内存泄漏与溢出
    v-on 绑定自定义事件
  • 原文地址:https://www.cnblogs.com/yankun1991/p/6992271.html
Copyright © 2011-2022 走看看