日期:2014-05-20  浏览次数:20781 次

对于 final 的理解, 希望高手做以详细解释。。
String s="a"; 
String s1=s+"b";
System.out.println(s1=="ab"); 
// 输出为false 

final String ss="a"; 
String ss1=ss+"b"; 
System.out.println(ss1=="ab"); 
// 输出为true 

根据上面的例子
谁能帮忙详细解释一下 final 的详细作用
看了很多文章,越看越糊涂,自己也是一知半解。。

------解决方案--------------------
刚看了这篇文章,http://www.51cto.com/art/200805/73338.htm
算是了解了,
说说我的浅显理解吧

s1=="ab",首先JVN去看s1是不是确定的"ab", s1=s+"b",到这就看s是不是确定的,String s="a";他不是常量,也就是不确定的...所以返回false.

下面那个可想而知,true了

这只是我的一点小理解
------解决方案--------------------
a == b 判断的是指针的相等。成立时表明a和b指向的是同一个位置的对象。

第二段用了final,java编译时已经把ss的值和"b"连接好,形成"ab"赋给ss1。此时编译器优化掉所有重复的"ab",所以ss1和"ab"常量引用同一个对象。

第一段没有final,s1是运行时产生的新对象。

避免这种问题,最好用String.equals去判断值的相等。
------解决方案--------------------
这个问题我觉得4楼说的最好~

总结一下final的用法,基本上就是三类:
1.final修饰变量的时候只能显式地赋一次值,一般的用途就是定义常量。但这个常量有可能因为对象的不同而不同,因为“显式地赋一次值”而不是“赋一次值”,因此如果有这样的定义:
final int a = 0;//这个a就是一个定义好的常量,以后不能被重新赋值
a = 1;//这个就不能通过编译

但是这样写:
final int a;//尽管这里Java自动给a赋过值了,其值为0,但不是显式赋值哦
a = 1;//这个是可以的:)

2.修饰方法的时候,说明这个方法是不能被重写的,比如
public class A{
public final void UnRewriteable(){}
}//定义一个final修饰的类

public class B extends A{
public void UnRewriteable(){}//这行会有编译错误
}



3.修饰类的时候,说明这个类是不能被继承的,比如String类就是被final修饰的一个类,所以不能有类似于public class test extends String 的类定义。


------解决方案--------------------
Java code

        //所有的字符串都存放在内存池中
        String s="a";  //"a"由于它是常量,所以它存放在常量池中
                   //s它是一个引用,不固定,想指向哪里就指向哪里,它存在栈中,它的地址放在堆中(里面存的是"a"的地址),它不是直接指向内存池中的"a"
        String s1=s+"b";//s+b 存放在堆中,s1指向它
        System.out.println(s1=="ab");//一个在堆中,一个在常量池中,肯定不相等啊("ab"它存放在内存池中


        final String ss="a";  //由于ss已经固定,它就指向"a",永不再变,所以它直接指向常量池中的"a"
        String ss1=ss+"b";   //ss+"b" 常量加常量还是常量,所以它存放在常量池中("ab")
        System.out.println(ss1=="ab"); //这个不相等才怪呢
        //对于常量字符串,系统会把它存放在内存池中,利于反复调用.
        //对于"ab",第一次存放由于常量池中没它的值,所以就给它分配了一块空间,但是当第二次存放时,常量池就不再为它分配空间,而是直接指向第一次的空间
        //所以常量池中的内容没有重复的

------解决方案--------------------
一:.equals("")方法进行值判断,则上例都为true;==判断内存地址;
二:
final声明的成员变量为常量不可更改,
final String ss="a"; 
String ss1=ss+"b"; 对象不会改变
System.out.println(ss1=="ab"); 
 
未声明final的值是可以改变的
String s="a"; 声明变量
String s1=s+"b"; 对象会改变
System.out.println(s1=="ab"); 
个人理解


------解决方案--------------------
引用楼主 Allen_Chao 的帖子:
String s="a";
String s1=s+"b";
System.out.println(s1=="ab");
// 输出为false

final String ss="a";
String ss1=ss+"b";
System.out.println(ss1=="ab");
// 输出为true