黑马程序员技术交流社区

标题: 由空字节数组转成的空字符和自定义空字符的比较问题 [打印本页]

作者: 李政    时间: 2013-7-24 14:15
标题: 由空字节数组转成的空字符和自定义空字符的比较问题
本帖最后由 杨兴庭 于 2013-7-24 20:52 编辑

我在琢磨UDP传输中使用readline方法中读取空行的时候,想到了获取到的应该是一个空字符,然后会转成的空字节数组。特意验证

了一下

System.out.println("".getBytes().length);//打印出的结果是0 这应该没错吧


这时候,突然想到字符串的对象在堆内存中是不变的,又随手打了些代码 ,这时候出问题了

                byte[] arr = new byte[0];//定义了一个空字节数组
               
                String line1 = "";//又定义了一个空字符串

                String line2 = new String(arr,0,arr.length);//将字节数组转成空字符串
               
                String line3 = "";

                System.out.println( line1 == line2);        //结果是false

                System.out.println( line1.equals(line2)); //调用equals方法,只比较字符串中的内容 结果是true

                System.out.println( line1 == line3);        //结果是true

为什么line1 == line2 ? 这时候会返回false呢?  字符串的中用  equals方法 和 == 两者之间有什么区别


作者: 诸隆隆    时间: 2013-7-24 15:05
....额  真的蛮闲的哈。   line1 == line2肯定是false,因为比较的是引用而不是具体的实例(也可以理解为比较的是地址而不是地址里面的内容),而equals对比的是里面的具体内容。line2是你new出来的,所以分配了新的地址。而line3,不是new的所以应该还是在字符串池中,引用也是不变的。
作者: 李政    时间: 2013-7-24 15:33
原来如此,明白了!
作者: 李政    时间: 2013-7-24 15:42
诸隆隆 发表于 2013-7-24 15:05
....额  真的蛮闲的哈。   line1 == line2肯定是false,因为比较的是引用而不是具体的实例(也可以理解为比 ...

我记得字符串常量池在内存中是一个独立的存储区域,它和方法区是不是一个区域呀?
作者: 郭俊    时间: 2013-7-24 15:53
本帖最后由 郭俊 于 2013-7-24 16:07 编辑

   String line1 = "";//   你这里定义的东西在 字符串常量池中
  String line2 = new String(arr,0,arr.length);  // 通过new了一个新的引用类型,它是放在堆中,同时栈中的引用类型变量(这里的line2)会指向堆中你new出来的东西!
不是一个区域!Java中内存可分为3个区:堆(heap)、栈(stack)和方法区(method)
堆区:存储的全部是对象(new出来的);

栈区:只保存基础数据类型的对象和自定义对象的引用(不是对象的);而且每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
方法区:又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。

作者: 李政    时间: 2013-7-24 15:55
郭俊 发表于 2013-7-24 15:53
String line1 = "";//   你这里定义的东西在 字符串常量池中
  String line2 = new String(arr,0,arr.le ...

字符串常量池在哪个区域
作者: 郭俊    时间: 2013-7-24 16:02
李政 发表于 2013-7-24 15:55
字符串常量池在哪个区域

常量池:存放基本类型常量和字符串常量;常量池是JVM的一块特殊的内存空间
作者: 李政    时间: 2013-7-24 18:52
版主 问题解决了




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2