问题描述
- 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?这是什么原理呢?
解决方案
final string 在编译的时候,值已经确定,a可替换成"hello",所以就是 "hello"+"2",这个形式的初始化会被编译器优化成"hello2"存在字符串常量区,由于str已经被初始化为"hello2",这个字符串已经存在于常量区,所以直接返回其引用,str==a.
b的值在编译时不确定,不能编译优化,所以d=b+"2",jvm会在堆中生成一个值为"hello2"的对象,返回引用给d。所以str不等于d
解决方案二:
普通变量,你执行拼接后赋予另一个变量,会在内存区域重新开辟一块儿进行存储。
对于final,则能够直接进行改变而不会进行重新开辟内存空间。
至于string型的比较,基本上是进行内容比较,会用equals进行比较的。
=进行比较,就设计到内容以及内存区域了比较了
解决方案三:
final变量在编译期间就已经确定了值,然后这个值是被存储到运行时数据区域中的常量池中的。
而你使用b+"2",是使用了引用变量b, JVM对于字符串引用,由于在字符串的"+"连接中,有字符串引用存在,而引用的值在程序编译期是无法确定的,即b+"2"无法被编译器优化,只有在程序运行期来动态分配并将连接后的新地址赋给d。所以上面程序的结果也就为false。
如果改成String d = "hello" + "2";那么str1==d就是true了,因为d本质上也是常量了。
解决方案四:
java中比较字符串,要用equals,不要用等号
解决方案五:
xxx.equals("xxx")
解决方案六:
输出false能理解吧。String d = b + "2";这句话生成了两个对象,等同于String d = new String("hello")+"2";所以第二个会输出false;
final 修饰String 之后,引用a也变成不可变量, String c = a + "2";这句话的效果就等于String c = "hello"+"2";,自然是true;
解决方案七:
a字符串加了final修饰,对于final修饰的变量,它在编译时被解析为常量值的一个本地拷贝存储到自己的常量池中或嵌入到它的字节码流中。
SString b = "hello";这种情况是引用数据类型,引用数据类型肯定存放在堆中 栈中放置的是参数变量而不能放对象 对象只能放在堆中,
可能是因为是对象,所以才不等吧
解决方案八:
static变量与普通变量的区别
static变量与普通变量的区别
C# 静态变量与普通变量的区别