final String

大家观察一下下面的代码为什么他们的值都是”ab“但是为什么他们结果却不是一样的哪?

		String a="a";
        final String b = "b";
        String ab1 = "ab";
        String ab2 = a + b;
        String ab3 = a + "b";
        String ab4 = "a" + b;
        String ab5 = "a" + "b";
        System.out.println(ab1 == ab2); //false
        System.out.println(ab1 == ab3); //false
        System.out.println(ab2 == ab3); //false
        System.out.println(ab1 == ab4); //true
        System.out.println(ab2 == ab4); //false
        System.out.println(ab3 == ab4); //false
        System.out.println(ab1 == ab5); //true
首先我们大家要知道“==”和“equals”是不同的。
“==”比较的是两个对象的地址是否相同,但“equals”比较的是两个对象的值是否相同。

在学习String时我们都知道String中有一个final,这也就是说明了String类型的变量在定义以后就是不能被改变,但是有人可能会问。

		String a="a";
        a="b";
        System.out.println(a);//b

在这段代码中a的值从原来的“a”变成了“b”,这不就是改变了吗怎么能说没有改变。
其实在内存中“a”的值的确是没有,只是a在最开始的时候把指引指向了一块存储了“a”地址的地方之后又改变了把指引指向了一块存储了“b”的地方,但“a”的那片内存并没有消失,只是没有变量指引了。

那么问题来了既然String的源码中都已经有final,那在String前再加一个final是什么意思?
在String前再加一个final是固定了它的指引,让他不会再指向别的地址。当加上final以后,这个值其实就已经在常量池中存在了,当调用这个变量时会把这个变量时,程序会把它当成一个常量来对待。那现在这也就能说明 String ab4 = “a” + b 其实就是 String ab4 = “a” + “b” ,应为在常量池中最先定义的是 ab1 所以 ab4 和 ab5 他们在定义时都共同指向 ab1,那为什么其他那几个值不指向 ab1 的地址那?是因为 Java 程序在运行的时候为了能够保证可以完整的编译,把那些不能解析成常量池中已存在的变量的值,给他们又重新开辟了一段地址把他们存了进去,因为变量 b 前加了 fianl 所以在调用它时被看作常量,而变量 a 前没有加 fianl 所以调用时不被当作常量。
如果你们不相信可以把他们的地址都打印出来看一下,下面是打印地址的代码。

System.out.println(System.identityHashCode(ab1));

猜你喜欢

转载自blog.csdn.net/MCYZSF/article/details/89890555
今日推荐