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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李宁 中级黑马   /  2013-1-15 18:56  /  1565 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 shaohuashang 于 2013-1-16 00:56 编辑
  1. Scanner input=new Scanner(System.in);
  2.   System.out.println("请输入abc:");
  3.   String s1=input.next();
  4.   String s2="abc";
  5.   if(s1==s2)
  6.    System.out.println("指向同一地址");
  7.   else
  8.    System.out.println("非同一地址");打印的是这句
复制代码
平时看到的只要字符串相同,地址应该也相同,为什么这个不同,请帮忙看下

评分

参与人数 1黑马币 +9 收起 理由
Rancho_Gump + 9 赞一个!

查看全部评分

5 个回复

倒序浏览
只要是字符串类型
String s1=input.next();

String s2="abc";
这是两个不同的对象
不管是赋值还是创建都是在堆内存中开辟新的空间,当然两个地址值不同了!
回复 使用道具 举报
String其实就是包装器类型,字面量地址值不能改变,String st1="abc" ,String st2="abc" st1==st2 返回ture
原理  st1 开辟了栈区,jvm默认给它分配的无符号了十六进制地址值,当 st2 开辟栈区之前,检查栈区是否有相同的字面值存在,据知 st2的字面值存在
那么 st1 的地址值 直接赋值给了 st2 ,栈区数据其实就是共享了 那么LZ 这儿 st2 与st1 字面值不同,st2 就要重新开辟栈区,jvm 自动分配地址值
所以 返回 是false ,注意 这儿String 类型 并没有开辟堆区,别弄错了, 若写出 String str=new String("abc") 这里才开辟了栈区同时开辟了堆区

评分

参与人数 1技术分 +1 收起 理由
Rancho_Gump + 1 赞一个!

查看全部评分

回复 使用道具 举报
String s1=input.next();这一句产生了String类型的对象,其字面值为"abc"但不在String pool中.String s2="abc";执行这一句时会先从String pool中查找字面值为"abc"的内存地址,因为找不到所以会开辟新的内存空间来存放"abc",由于他们的内存地址不同故用==比较对象是否完全相等时返回false
回复 使用道具 举报
s1 s2 在堆内存的引用地址不同,所以s1!=s2;
回复 使用道具 举报
java有一个常量池的概念,不过对于常量池的位置处于哪,我到现在也没弄清楚,之前和群里人讨论,得到2个结论,一个是位于堆内存中,但有点不靠谱,一个是位于方法区内。个人认为应该位于方法区内,下来说说楼主的问题,由于String s2 ="abc";由于编译时候已经确定了其值 所以在编译时候会加载进字节码,随着字节码的加载而初始化至常量池,而你用Scanner获取的由于编译时期无法确定值,所以需要在堆中新建一个String对象。这也就是为什么两个字符串地址值不一样的原因了。

评分

参与人数 1技术分 +1 收起 理由
Rancho_Gump + 1 赞一个!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马