2 wwq518 wwq518 于 2016.03.28 13:52 提问

final变量和普通变量的区别
        String str1 = "hello2";
        final String a = "hello";
        String b = "hello";
        String c = a + "2";
        String d = b + "2";
        System.out.println(str1 == c);
        System.out.println(str1 == d);

结果:
true
false
为什么第二个结果为false?这是什么原理呢?

8个回答

lxr0724
lxr0724   2016.03.28 14:12

final string 在编译的时候,值已经确定,a可替换成"hello",所以就是 "hello"+"2",这个形式的初始化会被编译器优化成"hello2"存在字符串常量区,由于str已经被初始化为"hello2",这个字符串已经存在于常量区,所以直接返回其引用,str==a.
b的值在编译时不确定,不能编译优化,所以d=b+"2",jvm会在堆中生成一个值为"hello2"的对象,返回引用给d。所以str不等于d

wenxuechaozhe
wenxuechaozhe   2016.03.28 14:01

普通变量,你执行拼接后赋予另一个变量,会在内存区域重新开辟一块儿进行存储。
对于final,则能够直接进行改变而不会进行重新开辟内存空间。
至于string型的比较,基本上是进行内容比较,会用equals进行比较的。
=进行比较,就设计到内容以及内存区域了比较了

wojiushiwo945you
wojiushiwo945you   Ds   Rxr 2016.03.28 17:09

final变量在编译期间就已经确定了值,然后这个值是被存储到运行时数据区域中的常量池中的。
而你使用b+"2",是使用了引用变量b, JVM对于字符串引用,由于在字符串的"+"连接中,有字符串引用存在,而引用的值在程序编译期是无法确定的,即b+"2"无法被编译器优化,只有在程序运行期来动态分配并将连接后的新地址赋给d。所以上面程序的结果也就为false。
如果改成String d = "hello" + "2";那么str1==d就是true了,因为d本质上也是常量了。

bdmh
bdmh   Ds   Rxr 2016.03.28 13:53

java中比较字符串,要用equals,不要用等号

wwq518
wwq518 我知道比较字符串用equals,为什么第一个为true,第二个为false呢?
2 年多之前 回复
bdmh
bdmh   Ds   Rxr 2016.03.28 13:53

xxx.equals("xxx")

luochoudan
luochoudan   Ds   Rxr 2016.03.28 14:17

输出false能理解吧。String d = b + "2";这句话生成了两个对象,等同于String d = new String("hello")+"2";所以第二个会输出false;
final 修饰String 之后,引用a也变成不可变量, String c = a + "2";这句话的效果就等于String c = "hello"+"2";,自然是true;

qq_16850743
qq_16850743   2016.03.28 14:26

a字符串加了final修饰,对于final修饰的变量,它在编译时被解析为常量值的一个本地拷贝存储到自己的常量池中或嵌入到它的字节码流中。
SString b = "hello";这种情况是引用数据类型,引用数据类型肯定存放在堆中 栈中放置的是参数变量而不能放对象 对象只能放在堆中,
可能是因为是对象,所以才不等吧

CSDNXIAOD
CSDNXIAOD   2016.03.30 11:28

static变量与普通变量的区别
static变量与普通变量的区别
C# 静态变量与普通变量的区别
----------------------biu~biu~biu~~~在下问答机器人小D,这是我依靠自己的聪明才智给出的答案,如果不正确,你来咬我啊!

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
final 变量和普通变量
看下面这个您呢个做对么? public class Test {     public static void main(String[] args)  {         String a = "hello2";         final String b = "hello";         String d = "hello";         String c = b
Java基础-final变量和普通变量的区别
当用final作用于类的成员变量时,成员变量(注意是类的成员变量,局部变量只需要保证在使用之前被初始化赋值即可)必须在定义时或者构造器中进行初始化赋值,而且final变量一旦被初始化赋值之后,就不能再被赋值了。 那么final变量和普通变量到底有何区别呢?下面请看一个例子: public class Test { public static void main(String
Java final变量和普通变量的区别
Java final变量和普通变量的区别今天在查看以前在达内培训的笔记时候,发现了Final关键字的使用笔记,其中有一个是关于Java类中final变量和普通变量的区别。对于java开发人员来说,final关键字是不陌生的,因为在使用匿名内部类的时候可能会经常的用到final关键字。翻看笔记,在博客里面记录下来final变量和普通变量的区别,有不正之处,希望大神指正。当用final作用于类的成员变量
Java-实例变量、局部变量、类变量与final变量的区别
把Java中的实例变量、局部变量、类变量与final变量之间的关系的思路重新整理一遍。俗话说的好“好记忆不如烂笔头”,在此分享一下。
java基础-ThreadLocal变量和普通变量的区别
java提供了ThreadLocal这个类型,具有该类型的成员变量,每个使用到该变量的线程都保留一份该属性的备份数据,在线程内部对该属性的操作都是自己备份的数据,所以声明为ThreadLocal类型的成员变量都是线程安全的。       简单测试了一下ThreadLocal类型的成员和普通成员的区别,在多线程环境,每个线程都会存有一个ThreadLocal的值,而普通成员则是线程共享的。 im
再说final变量
从jdk1.0到今天,JAVA技术经过十余年的发展,技术上已经发生了巨大的变化.但final变量的定义从它诞生那天起,就没有发生任何变化,也就是这十多年它就一直表示它原来的意思.但遗憾的是,经过十多年仍然有90%的人没有理解它的真实含义,也没有一篇文章,包括我所见到的所有介绍JAVA的书籍(包括TKJ)都没有说清楚,我相信肯定有些作者是理解的,但没有一个作者向读者说清楚.而中国网友大多数人被一篇胡
final修饰基本类型和引用类型变量的区别
当使用final修饰基本类型变量时,不能对基本类型变量重新赋值,因此基本类型变量不能被改变。但对于引用类型的变量而言,它保存的仅仅是一个引用,final只保证这个引用所引用的地址不会改变,即一直引用同一个对象,但这个对象完全可以发生改变。 final int[] iArr={6,8,9,10} //对数组进行排序,合法 Arrays.sort(iArr); System.out.p
java final变量详解
java final变量详解 java final变量详解 java final变量详解 java final变量详解
对c语言普通变量和指针变量的理解
一、普通变量和的本质区别        在说到普通变量和指针变量的区别时,我更喜欢从一个更高的视角去看待这两者。首先来说,这两者都是变量,既然是变量,就会包含地址和值这两部分,例如int a , 用&a获得该变量的地址,用a获得改地址的值;普通变量的指针变量的区别就是,这两种变量的值的所表示的意义不同, 一般来说,普通变量的值,只是供程序员所使用的值,而指针变量的值则不同,它的值存放的是其...
java中的final变量
【java中为什么会有final变量】: final这个关键字的含义是“这是无法改变的”或者“终态的”; 那么为什么要阻止改变呢? java语言的发明者可能由于两个目的而阻止改变: 1).效率问题: jdk中的某些类的某些方法,是不允许被用户覆盖的,设计者可能认为,所用方法已经是最好的方法, 用户私自覆盖,或是由于疏忽而覆盖,就会影响JVM或是系统的系能; 2). 设计所需: 众所