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

程序如下:
  1. class Test {
  2.     public static void main(String[] args) {
  3.         String a1 = "ab";
  4.         String a2 = "b";
  5.         String a3 = "a" + a2;
  6.         System.out.println(a1 == a3);// 打印:false
  7.         // ————————————————————
  8.         String b1 = "ab";
  9.         final String b2 = "b";
  10.         String b3 = "a" + b2;
  11.         System.out.println(b1 == b3);// 打印: true
  12.         // ————————————————————
  13.         String c1 = "ab";
  14.         final String c2 = get();
  15.         String c3 = "a" + c2;
  16.         System.out.println(c1 == c3);// 打印: false
  17.     }

  18.     public static String get() {
  19.         return "b";
  20.     }
  21. }
复制代码

求大神解释打印结果。

4 个回复

正序浏览
本帖最后由 叫我斯文哥 于 2015-7-29 15:46 编辑

      当final变量是基本数据类型以及String类型时,如果在编译期间能知道它的确切值,则编译器会把它当做编译期常量使用。也就是说在用到该final变量的地方,相当于直接访问的这个常量,不需要在运行时确定。这种和C语言中的宏替换有点像。因此在上面的一段代码中,由于变量b2被final修饰,因此会被当做编译器常量,所以在使用到b2的地方会直接将变量b2 替换为它的值。而对于变量a2的访问却需要在运行时通过链接来进行。要注意,只有在编译期间能确切知道final变量值的情况下,编译器才会进行这样的优化,第三段的代码就不会进行优化,因为在编译时c2还不知道变量的值。 还有常量用‘==’比较,字符串要用equals  比较。
       对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
回复 使用道具 举报 1 0
我的理解是:除了第二个的b3可以在编译期被优化,b1和b3在编译期就能确定为常量池中的“ab”,第一个的a3和第三个的c2、c3编译期无法确定,都是在运行期开辟新的内存运算后创建一个新的对象
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马