A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 焦健 高级黑马   /  2013-1-24 00:18  /  1849 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 焦健 于 2013-1-24 00:20 编辑

请问大家,为什么将一个字符串转换为一个byte数组,并且存入到一个已经定义好的byte数组中,那么这个数组的地址值就会改变。我们知道字符串的改变改变的是地址的引用,但是byte不是引用数据类型,那么它本身的地址为什么会改变呢。在云二发了同样的问题,不小心发错板块了。。版主能否帮忙去删一下。。
  1. public class Test5 {

  2.         public static void main(String[] args) {
  3.                 // TODO Auto-generated method stub
  4.                 byte[] arr=new byte[5];
  5.                 System.out.println(arr.length+"--"+arr.hashCode());
  6.                 arr[1]=3;
  7.                 arr[0]=2;
  8.                 System.out.println(arr.length+"--"+arr.hashCode());
  9.                 String str="abc";
  10.                 arr=str.getBytes();
  11.                 System.out.println(arr.length+"--"+arr.hashCode());
  12.                
  13.         }

  14. }
复制代码
接下来是这一段代码运行的结果,请大家帮忙分析一下。。
  1. 5--6613606
  2. 5--6613606
  3. 3--22608339
复制代码

评分

参与人数 1黑马币 +9 收起 理由
金鑫 + 9

查看全部评分

7 个回复

倒序浏览
//在堆内存创建个数组,并赋予地址,arr指向那个地址,假设地址是A
byte[] arr=new byte[5];

//这时根据地址A给出个哈希值
System.out.println(arr.length+"--"+arr.hashCode());

//你地址A那个数组更换2个元素
  arr[1]=3;
   arr[0]=2;

//由于arr依然指向地址A,所以没变化,哈希值没变
System.out.println(arr.length+"--"+arr.hashCode());

//把abc字符串赋给str
String str="abc";

//重点getBytes()方法,我从api的介绍搬过来是:“使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。”
//也就说这时arr指向了另外1个内存地址,比如地址B
arr=str.getBytes();

//由于arr依然指向地址B,所以哈希值变了
System.out.println(arr.length+"--"+arr.hashCode());


如果错了,请指教~我也不知道是不是这样




评分

参与人数 1技术分 +1 收起 理由
金鑫 + 1

查看全部评分

回复 使用道具 举报
LZ的疑问实际上是哈希值 HashCode 在作怪....下面听我解释...{:soso_e144:}
  1. public class Test5 {
  2.         public static void main(String[] args) {
  3.                 byte[] arr=new byte[5];
  4.                 System.out.println(arr.length+"--"+arr.hashCode());
  5.                 arr[1]=3;
  6.                 arr[0]=2;
  7.                 System.out.println(arr.length+"--"+arr.hashCode());
  8.                 String str="abc";
  9.                 arr=str.getBytes();
  10.                 System.out.println(arr.length+"--"+arr.hashCode());
  11. }
  12. }
复制代码
JVM 将 对象arr的hashcode丢在一个HashTable 哈希表里对应的Key 上, 而这里是系统自动生成整数型 的hashcode值,实际上就是散列集合
由于hash算法有多种...,这里str.getBytes(),调用的此方法,与参与散列对象str就要重新计算它的hashcode,并把引用地址赋值给了arr,arr的hashcode就是
str引用地址的后面无符号的十六进制的八位数,arr 进行的初始化运算,并没有参与散列对象,所以hashcode 没重新计算,
调用的是系统缓存的hashcode,注意:一个对象不是所有属性都参与散列


在集合里Map接口的集合框架都要实现覆写 equals() 和 hashcode( ) ,原因就在这里,值得好好思考,反过来说 hashcode能代表对象所在内存地址吗?LZ好好思考,好好掂量....






评分

参与人数 1技术分 +1 收起 理由
金鑫 + 1

查看全部评分

回复 使用道具 举报
楼上的解释挺详细的,关键是equals() 和 hashcode( ) 两个函数,hashCode方法实际上返回的就是对象存储的物理地址(实际可能并不是):
1、如果两个对象相同,那么它们的hashCode值一定要相同;
2、如果两个对象的hashCode相同,它们并不一定相同     上面说的对象相同指的是用eqauls方法比较。  
回复 使用道具 举报
byte不是引用数据类型,这个你说得没错,但是,byte[]是引用数据类型。引用数据类型有 类、接口、数组
回复 使用道具 举报
在java中除了4类八种基础数据类型之外,全部是引用数据类型,包括数组,object类中hashcode()方法是根据特定的算法将对象的地址转换成某个值,画一幅图给你看吧
画的不好,将就着看吧
回复 使用道具 举报
焦健 高级黑马 2013-1-24 18:15:16
7#
啊。谢谢楼上几位兄弟了。。我明白了。。哈哈。多谢啦。。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马