zoukankan      html  css  js  c++  java
  • 认识string的深度到底 有多深?(值类型与引用类型的Equals到底 差在哪?)

    大部分人都对引用类型熟悉,乃至精通,大家都知道对于一个类,声明2个引用对象的变量,那么这2个变量的Equals,如果是引用了相同的对象那么可能是true,如果引用了不同的对象必然是False:

    第一题:

    Test one = new Test();
    Test two = new Test();
    Console.WriteLine("one == NUll:{0}", one == null);//false
    Console.WriteLine(one.Equals(two));//false
    Console.WriteLine(Test.Equals(one, two));//fase
    Console.WriteLine(Test.ReferenceEquals(one, two));//false

    对,或许你答对了,这就是我们的理论没错。

    但是,请大家看下面的列子:

    第二题:

    Test one = new Test();
    Test two = one;
    Console.WriteLine(one.Equals(two));//true
    Console.WriteLine(Test.Equals(one, two));//true
    Console.WriteLine(Test.ReferenceEquals(one, two));//true

    可能你的答案又对了,因为咱们知道对于一个引用变量赋值给一个新的引用变量,就是把引用该对象的内存地址赋值给了新引用变量,也就是把 指向对象的指针传递给了新引用变量。

    这里:大家都知道,one two 2个引用变量  对象的对象是同一个对象,那么只要one 修改对象,那么two对应的对象也会改变。(two修改对象One也会改变)

    如果以上都看懂了,你可以进入下一题:

    第三题:

    string s1 = "123";
    string s2 = s1;
    Console.WriteLine(s1.Equals(s2));//true
    Console.WriteLine(string.Equals(s1, s2));//true
    Console.WriteLine(string.ReferenceEquals(s1, s2));//true

    上面这题???你答对了吗?

    分析:

    1.string是类,s1 s2是变量,储存在堆栈上(和值类型一样),在堆上建立2块内存新建2个对象(对象在堆上),应该说Equals的结果是False,为何true?

    答案如下:

    [引用 徐洪强博客]:

    "CLR使用了一种叫字符串驻留的技术,对于
    string   str1="abc";
    string   str2="abc";
    当CLR初始化时,会创建一个内部的散列表,其中的键为字符串,值为指向托管堆中字符串的引用。刚开始,散列表为空,JIT编译器编译方法时,会在散列表 中查找每一个文本常量字符串,首先会查找"abc"字符串,并且因为没有找到,编译器会在托管堆中构造一个新的指向"abc"的String对象引用,然 后将"abc"字符串和指向该对象的引用添加到散列表中。
      接着,在散列表中查找第二个"abc",这一次由于找到了该字符串,所以编译器不会执行任何操作,代码中再没有其它的文本常量字符串,编译器的任务完 成,代码开始执行。执行时,CLR发现第一个语句需要一个"abc"字符串引用,于是,CLR会在内部的散列表中查找"abc",并且会找到,这样指向先 前创建的String对象的引用就被保存在变量s1中,执行第二条语句时,CLR会再一次在散列表中查找"abc",并且仍然会找到,指向同一个 String对象的引用会被保存在变量s2中,到此s1和s2指向了同一个引用,所以System.Object.Equals(s1,s2)就会返回 true了。
    "

    好了进入下一题

     //引用类型
    string s1 = "123";
    string s2 = s1;
    s1 = "123456";//新建一个对象
    Console.WriteLine(s2);//输出结果是:123


    总结下经过3天的激烈讨论:

    问题集中在 最后一题

    当s2=s1的时候,只是s1 s2的指针都指向了“123”,当s1="123456"的时候新建了堆里的对象,那么s1的指针改变了,s2却为改变。

    针对:

    "CLR使用了一种叫字符串驻留的技术,对于
    string   str1="abc";
    string   str2="abc";

    这种技术才是驻留技术。

  • 相关阅读:
    215. Kth Largest Element in an Array
    B:魔兽世界之一:备战
    218. The Skyline Problem
    编程作业: 编程作业—类和对象
    239. Sliding Window Maximum
    313. Super Ugly Number
    hdu3068 manacher模板题
    fzu1901 kmp
    hdu2609 最小表示法
    hdu3374 kmp+最小表示法
  • 原文地址:https://www.cnblogs.com/IAmBetter/p/2304365.html
Copyright © 2011-2022 走看看