zoukankan      html  css  js  c++  java
  • 装箱与拆箱

    一、装箱机制:

    1,在托管堆中分配内存。分配的内存量是值类型各字段所需的内存量,还要加上托管堆中所有对象都有的两个额外成员(类型对象指针和同步块索引)所需的内存量
    2,值类型字段复制到新分配的堆内存
    3,返回对象地址。现在该地址是对象的引用;值类型成了引用类型

    二、拆箱机制

    1,获取已装箱值类型对象中的各个字段的地址(这个过程是装箱)
    2,将字段包含的值从堆复制到基于栈的值类型字段实例中
    3,如果包含“对已装箱值类型实例的引用”的变量为null,抛出NullReferenceException异常
    4,如果引用对象不是所需值类型的已装箱实例,抛出InvalidCastException异常

    三、未装箱值类型比引用类型更“轻”,这要归结于以下两个原因

    1,不在托管堆上分配
    2,堆上的每个对象都有两个额外成员(“类型对象指针”和“同步快索引”)。

    四、对象相等性和同一性

    1,对于Object的Equals方法的默认实现,他实现的实际是同一性,而不是相等性

        public class Object
        {
            public virtual bool Equals(object obj)
            {
                //如果两个引用指向同一个对象,他们肯定包含相同的值
                if (this == obj)
                    return true;
                //假定对象不包含相同的值
                return false;
            }
        }

    2,正确的实现Equals
    ①,如果obj实参为null,就返回false,因为调用非静态Equals方法时,this所标识的当前对象显然不为null
    ②如果this和obj实参引用同一个对象,就返回true。在比较包含大量字段的对象时,这一步有助于提升性能
    ③如果this和obj实参引用不同类型的对象,就返回false
    ④针对类型定义的每个实例字段,将this对象中的值与obj对象中的值进行比较。任何字段不相等,就返回false
    ⑤调用基类的Equals方法来比较它定义的任何字段。如果基类的Equals方法返回false,就返回false;否则返回true

        public class Object
        {
            public virtual bool Equals(object obj)
            {
                //要比较的对象不能为null
                if (obj == null) return false;
    
                //如果对象属于不同的类型,则肯定不相等
                if (GetType() != obj.GetType()) return false;
                
    
                //如果对象属于相同的类型,那么在它们所有字段都匹配的前提下返回true
                //由于System.Object没有定义任何字段,所以不用比较
                return true;
            }
        }
    //比较对象的同一性
                object.ReferenceEquals(obj1, obj2);

    3,ValueType的Equals内部是这样实现的
    ①如果obj实参为null,就返回false
    ②如果this和obj实参引用不同类型的对象,就返回false
    ③针对类型定义的每个实例字段,都将this对象中的值与obj字段中的值进行比较(通过调用字段的Equals方法)。任何字段不相等,就返回false
    ④返回true,ValueType的Equals方法不调用Object的Equals方法

    学习永不止境,技术成就梦想。
  • 相关阅读:
    Java 动态编译
    在ubuntu 18.04下,无线网卡无驱动,连不上wifi,显示wifi没有适配器的解决方法
    由浅入深了解Thrift(1,2,3)
    Docker系列05:docker镜像制作 &Docker file
    Docker系列04:docker数据存储
    Docker系列03:docker网络
    关于在github上 下载源码 clone 非 master 分支的代码
    CentOS 6 & 7 忘记root密码的修改方法
    Windows RDP远程连接CentOS 7
    Windows 上用IntelliJ Idea调试百度大数据分析框架Apache Doris FE
  • 原文地址:https://www.cnblogs.com/zd1994/p/6492694.html
Copyright © 2011-2022 走看看