当final变量引用一个对象时,是指引用本身恒定不变,而不是指引用的本身不变。 
可是下面这个题怎么会这样?
        int[] b = {1,2,3};
final int[] a = b;
b[2] = 4;
System.out.println(a[2]); 
输出的结果却是4?????  它们的引用是指向同一个对象,b[2]=4把值给改变了,所以应该a[2]的值也会改变!但这个final关键字是不是有点多余,跟第一句讲的有点矛盾了???

解决方案 »

  1.   

    final int[] a = b;
    a所引用的对象不能再改变
    比如
    a = new int[];
      

  2.   

    应该是引用本身不能变化,但引用的对象里面的属性可以变化吧。比如final User u=new User();
    这样以后u就不能指向其他user了。但是
    u.setName("")之类的操作还是可以执行。套用到你上面的例子也是这样解释,a的引用不能再发生变化,但a指向的对象里面的属性却可以变化
      

  3.   

    int[] b = {1,2,3};
    final int[] a = b;
    a只是引用b,它不能再引用其他变量。而
    b可以改变,他不是final
    b[2] = 4;
    System.out.println(a[2]);
      

  4.   

    final的变量引用过程中只能读取,不能修改
      

  5.   

    一个变量被赋上final表示这个变量是终极的,不能被修改,而变量是用来存储值的.对于基本数据类型,存储的事数据的值;对于引用类型变量,存储的是引用值.所以,作为对象引用变量a表示的是其引用不变.而不是为a克隆一个对象,令其为a所独享."是指引用本身恒定不变,而不是指引用的本身不变"
    楼主这句话实在是不知所云.
      

  6.   

    如果不用final,就会开辟了两个内存,数组a和b的,你认为两个不相干的内存,如果改变了其中一个内存中的数据后,另一个会改变吗?但是你对a添加final 前缀后,a只是引用了b的内存空间,就是说不能对a进行改变值,但是你的a连接的是一个值会动态改变的数组b,所以你可以改变b的值,a反映出来的值肯定会改变,但是你并不能通过改变a来改变b。
      

  7.   

    楼主对比下如下的代码可能更应该明白了         int a[]={1,2,3};
             int c[]={2,3,4};
             final int b[]=a;
            
             //下面这里是重新给final引用赋值。
              //报告:The final local variable b cannot be assigned. It must be blank and not using a compound assignment
             b=new int[]{22,33,44};  
             a[2]=4;
             System.out.println(b[2]);
    对于final声明的引用来说,是不允许其改变的.再如:
            //参数param是Object对象类型,被声明final后,你不可以修改这个参数的值
             //当你讲param这个引用指向一个另外的Object类的实例后,会报告上面一样的错误
    public void doSomething(final Object param){
    param=new Object();
    }
    对于使用final修饰类型,
    1 基本数据类型变量,用final修饰后 不可以将其修改值
    2.对于对象引用类型,用final修饰后,不可以将这个引用修改,但引用所指向的对象的“内容”是可以被修改的。
      

  8.   

    说白了。:
    对象a 加了final   那么就说明他绑定到了B 也就是指针指向了B  如果B有修改 那么他也跟着被修改。
    但是 不能更改a本身的值。lz 的 这句话 :“是指引用本身恒定不变,而不是指引用的本身不变。”  ---表示的就是  不能更改a指向的对象  但是可以改进所指对象的内容
      

  9.   

    说白了。:
    对象a 加了final   那么就说明他绑定到了B 也就是指针指向了B  如果B有修改 那么他也跟着被修改。
    但是 不能更改a本身的值。lz 的 这句话 :“是指引用本身恒定不变,而不是指引用的本身不变。”  ---表示的就是  不能更改a指向的对象  但是可以改进所指对象的内容
      

  10.   


    // 对于使用final修饰类型,
    // 1 基本数据类型变量,用final修饰后 不可以将其修改值
    // 2.对于对象引用类型,用final修饰后,不可以将这个引用修改,但引用所指向的对象的“内容”是可以被修改的 int a[] = { 1, 2, 3 };
    int c[] = { 2, 3, 4 };
    final int b[] = a;
    int[] d = new int[] { 11, 22, 88 };
    c = d; // 这里赋值成功
    /*
     * 下面一句b=d; 会报错 ,d是一个新对象,试图将一个新的引用赋给b, 而b又是final类型的, 不能改变对象引用,所以就报错
     */
    b = d;
      

  11.   

    一点不矛盾,final int[] a = b; 表示a的引用和b的引用是相同的,他们都指向了同一个对象。
     b[2] = 4; 表示你要改变b所指向的对象中第三个数(也就是b[2])的值,所以你输出a的时候会是4
      

  12.   

    简单的说,final修饰变量不要使用赋值操作符。
    final限定的是它限定的变量,就这么简单。
    举个例子:public class Test {
    public static void main(String[] args){
     final int i = 5;
     final StringBuilder str = new StringBuilder("Hello ");
     final int[] array = {1,2,3};  /*
     !!Error!!
                     要修改final修饰的变量,显然是不允许的。 
     i = 8;
     str = new StringBuilder("World!");
     array = new int[]{4,5,6};
     */
     str.append("World!" );//修改str所引用对象的内容,final管不着了
     array[2] = 5; //同上
    }
    }看个图:
    final所限定变量里的东西不让修改了。但堆里的东西是应该由类施加限制的,比如定义成员变量为final的(学习String)。
    对于数组,java没办法限定不让修改的。
      

  13.   

    int[] b = {1,2,3};
    final int[] a = b;//a指向的是b对象  a不可变,但是B对象却是可变的
    b[2] = 4;
    System.out.println(a[2]);