为了账号安全,请及时绑定邮箱和手机立即绑定

String定义的不同名字的变量,但是内容都一样,这些变量的地址都一样吗?本人java小白。

我用String定义了三个变量a="HELLO";b="HELLO";c="HELLO",a,b,c内容相同,他们对应的地址也相同吗?地址是不是在栈里,内容在堆里?本人java小白,望大神指导,不胜感激。

正在回答

6 回答

题主上图可以用这篇文章来解释。我把具体解释的地方复制过来哈

2-一个字符串=两个字符串相加; 4-一个字符串=一个常量加一个字符串

* 【二】 2和4放在一起说,因为他们的本质是一样的。

 * 对于2和4,如果用开始的那个等式来套用下,结果应该都是true,但java给出了false,看来不是这个等式有问题就是java对这个

 * 等式的处理有问题。事实是等式没有问题,问题在java对这个等式的处理方式上。

 * 当+号中有变量时(这里的变量指严格意义上的变量,除了直接的字面上的字符,所有需要一次以上处理才能成为直接字面字符的     值存在时 java都一律将其视为变量),因为对于s2+s3和"Zhou"+s3,java并不知道这里面到底是什么,从上面的定义看,它只知     道这个变量是String类型的(对于运行前的编译来说这些信息足够了),既然是变量,那么java都会放在运行期才会去确定变量的具     体值。

* ——PS:这里的解释放在多态里面也是通用的,即:子类的对象引用赋值给父类的引用,编译时只会检查是否具有继承关系,也    就是检查是否是同一个类型的,至于具体的值不管,运行期间再说,最终的效果就是运行时的多态。

* 所以有句话很经典:覆盖是运行时的多态。因为子类的行为状态覆盖了父类的行为状态。

* 接着说字符串,既然都是变量,跟多态的原理一样,java会在运行的时候去处理+号两边的变量。但是具体的方式不一样,对于字    符串的运算,如果是变量,那么java会先new出一个StringBuilder(在JDK6.0之前是StringBuffer),然后调用append()方法

* 来将+号两遍的字符串拼接起来(底层就是char数组的拼接),然后toString()之后返回给=号左边的变量,也就是说,最后得到的

* 是一个new出来的字符串,那么这个字符串必然是在堆中了。结果就必然会是false了。

* 2和4,一个+两遍都是变量,另一个只有一个变量,但对于java来说,只要是变量,它就会去new一个StringBuilder来拼接,对

* 它来说这没有什么区别。

* 顺便解释一下s4的运算机制,对于s4的+两边都是字面字符常量来说,java在编译期就将+两边拼接合并了而不会等到运行时再        算,因为在java看来,这样的运算即使放到运行时也不会有变化,运行期间重点要解决的是变化的东西。

0 回复 有任何疑惑可以回复我~
#1

Gir非碼農

惭愧至极,这问答确实也让我获益匪浅,当初学习的时候也没有重视这里,只是想当然把这里记牢就过去了。感谢题主,我又深层复习了一次。实际上这个问答已经涉及到很深了。具体到符号的功能和含义,还有jvm底层的运行模式
2018-02-26 回复 有任何疑惑可以回复我~
#2

慕先生9706129 提问者 回复 Gir非碼農

难怪文章里好多内容我看了都迷糊哈哈,我是任重道远啊,今天是学java的第二天,白天上班,下班还得等孩子睡着了学,感觉以前浪费太多时间了,只能珍惜现在了。
2018-02-26 回复 有任何疑惑可以回复我~
#3

进击的程序女袁 回复 慕先生9706129 提问者

学习容易,学好不易。加油!我还是个宝宝。
2018-02-26 回复 有任何疑惑可以回复我~

我用String定义了三个变量a="HELLO";b="HELLO";c="HELLO",a,b,c内容相同,他们对应的地址也相同吗?

---- 是的。

除非 这里你是 用b和c 是 new String("HELLO")  ,才会用新开辟一个内存空间装"HELLO"。这时地址不同。

否则  会复用第一次的那个a="HELLO" , 这是字符串的特性.这时地址相同。

内部维护了一个常量池,可以参考String的intern方法

0 回复 有任何疑惑可以回复我~

http://img1.sycdn.imooc.com//5a94113700016c2c05670153.jpg这个为什么是false

0 回复 有任何疑惑可以回复我~
#1

Gir非碼農

对于“+”的问题,在对两个字符串常量时,是连接 对连接中包含有字符串变量时就是转化。涉及到apend和toString两个函数…… 比较绕,我引述的这文章讲的比较好,你可以看看
2018-02-26 回复 有任何疑惑可以回复我~

http://img1.sycdn.imooc.com//5a940c820001b66807240243.jpg

有些尴尬,刚说完==只能用数字,就被自己打脸……学无止境

==用于比较引用和比较基本数据类型时具有不同的功能:
比较基本数据类型,如果两个值相同,则结果为true
而在比较引用时,如果引用指向内存中的同一对象,结果为true

对象问题,a与b为一个对象,都指向同一池的hello。

其他都互为非同一个对象。a-c,a-d,b-c,b-d。

不是同一对象,==为false,但对应的值相同,equals为true。

0 回复 有任何疑惑可以回复我~
#1

慕先生9706129 提问者

这个能帮我讲一下吗?下图
2018-02-26 回复 有任何疑惑可以回复我~
#2

Gir非碼農 回复 慕先生9706129 提问者

是我发的这个图还是一会你要发个图……
2018-02-26 回复 有任何疑惑可以回复我~
#3

Gir非碼農 回复 Gir非碼農

看到了
2018-02-26 回复 有任何疑惑可以回复我~

在编程中,通常比较两个字符串是否相同的表达式是“==” ,但在 Java 中不能这么写。在 Java 中,如果要比较 a 字符串是否等于 b 字符串,需要这么写: if(a.equals(b)){ } 返回 true 或 false equals()方法 方法 String 的 equals()方法用于比较两个字符串是否相等。由于字符串是对象类型,所以不能 简单的用“==” (双等号)判断两个字符串是否相等,而使用 equals()方法比较两个对象的内 容。 语法: boolean equals(String str) str:要作比较的字符串对象。 返回:如果和 String 相等则为 true;否则为 false。 例如字符串“abc” 和一个新的字符串“abc” 比较的结果为“true” 因为它们内容相同。 , 注意: equals()方法比较的是对象的内容(区分字母的大小写格式) ,但是如果使用“==”双等 号操作符比较两个对象时, 比较的是两个对象的内存地址, 所以它们不相等 (即使内容相同, 不同对象的内存地址也是不相同的)

这段话来源于   这里

能用==相连的是数字,int double float。

equals()相连的是string。

至于地址问题,网上也有详细介绍,我就不舞刀弄枪献丑了。推荐看看这个。讲的比较简单易懂。

哎,这回的回答都是借鉴的别人现成的。汗

0 回复 有任何疑惑可以回复我~

地址自然不相同啊。

他们的变量名字不同,存储的地址自然也不同。变量名背后代表的就是 存储地址。

存储地址就是一个内存编号。这个地址块里面的内容就是HELLO字符串。

址是不是在栈里,内容在堆里。这个 说法不存在。

0 回复 有任何疑惑可以回复我~
#1

慕先生9706129 提问者

它们之间比较时a==b;b==c;结果是true,a,b,c之间比较的是HELLO字符串吗?
2018-02-26 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消

String定义的不同名字的变量,但是内容都一样,这些变量的地址都一样吗?本人java小白。

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信