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 的详细作用
看了很多文章,越看越糊涂,自己也是一知半解。。

解决方案 »

  1.   

    刚看了这篇文章,http://www.51cto.com/art/200805/73338.htm
    算是了解了,
    说说我的浅显理解吧s1=="ab",首先JVN去看s1是不是确定的"ab", s1=s+"b",到这就看s是不是确定的,String s="a";他不是常量,也就是不确定的...所以返回false.下面那个可想而知,true了这只是我的一点小理解
      

  2.   

    a == b 判断的是指针的相等。成立时表明a和b指向的是同一个位置的对象。第二段用了final,java编译时已经把ss的值和"b"连接好,形成"ab"赋给ss1。此时编译器优化掉所有重复的"ab",所以ss1和"ab"常量引用同一个对象。第一段没有final,s1是运行时产生的新对象。避免这种问题,最好用String.equals去判断值的相等。
      

  3.   

    .equals("")判断字符串的值是否相等。
    ==判断内存地址。这个应该不是final的问题。
      

  4.   

    这个问题我觉得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 的类定义。
      

  5.   


    //所有的字符串都存放在内存池中
    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",第一次存放由于常量池中没它的值,所以就给它分配了一块空间,但是当第二次存放时,常量池就不再为它分配空间,而是直接指向第一次的空间
    //所以常量池中的内容没有重复的
      

  6.   

    "="是比较内存地址的.想比较内容就像其他同志所说的那样用"equal()"函数
    "final" 只能显式地赋一次值
    final  String a="dfds";//相当于C++中的const String a="dfds" 是常量,不变
      

  7.   

    一:.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"); 
    个人理解
        
      

  8.   

    第一个输出为false原因是:在s1+"b"这句,编译的时候会变成
    new StringBuilder.append(s).append("b").toString();
    看看上边这句话,toString();是产生了一个新的string对象
    这个是StringBuilder()的toString()方法    public String toString() {
            // Create a copy, don't share the array
    return new String(value, 0, count);
        }而对于第二个例子,对于final类型的常量,编译时相当于
    把这句String ss1=ss+"b";
    变成了String ss1="a"+"b";
    再优化String ss1="ab";
    所以也就相等了。
      

  9.   

    final 修饰方法不能被子类重写
    final 类不能被继承
    final 变量是常量