对于 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