class Value {
int val = 0;
}
public class Test{
public static void funValue(Value v){
v = new Value();
++v.val;
}
public static void funValueFinal( final Value v){//final没什么作用啊
//!v = new Value();
funValue(v);
}
public static void main(String[] args){
Value a =new Value();
System.out.println("a.val="+a.val);//对象a这个a.val=0
funValueFinal(a);//调用method,也很明显啊
System.out.println("a.val="+a.val);
}
}//两个a.val都是类对象的,都是零,后面那些method只是传递一个副本

解决方案 »

  1.   

    这个问题和c++里面的const实现是一样
    给参数加上final(或const)的限制就是为了达到引用传递进来的指的一个指针地址,从而提高效率,但是又不允许函数内部修改这个地址上的变量或者对象的值针对上面的代码,第一个输出肯定没有问题
    第二个其实也很好解释,调用funValueFinal时,主函数里的Value a就不会被修改其地址。在funValueFinal里调用funValue时尽管把原来的a传进去了,但funValue里又有这么一句
    v = new Value();它的作用是新建一个对象,这时就不在是对原来的那个对象进行操作了,所以原来那个对象是不会改变的
    那第二个输出还是0也就不足为奇了
      

  2.   

    java中的一切都是传值调用,所以funValueFinal( final Value v)中把v的值传给了funValue(v);funValue(v)接受到一个v参数,而此中的v不是final的,所以可以改变的.
      

  3.   

    搂主:
    我对输出的结果没什么异议,但是大家要注意到我写的问题,funValueFinal是一个不允许改变参数指向的函数,但它却调用了一个可以改变参数指向的函数,这本身就很矛盾啊!写的明白点
    funValueFinal(final Value v)//final告诉编译器v不能重新指向别的对象,
    funValue(Value v)//v可以重新指向别的对象,也可以不变化
    那和明显的是:
    funValueFinal(final Value v){
        funValue(v);  //这个绝对有可能使v指向新的对象,这不是和final矛盾了吗???
    }
    希望大家解释一下。
      

  4.   

    funValueFinal(final Value v){
        funValue(v);  //这个绝对有可能使v指向新的对象,这不是和final矛盾了吗???
    }
    这个传递的就是对象的副本了吧
      

  5.   

    class Value {
    int val = 0;
    }
    public class FinalArgument{
    public static void funValue(Value v2){
    v2 = new Value();
    ++v2.val;
    }
    public static void funValueFinal(final Value v1){
    //!v1 = new Value();
    funValue(v1);
    }
    public static void main(String[] args){
    Value a =new Value();
    System.out.println("a.val="+a.val);
    funValueFinal(a);
    System.out.println("a.val="+a.val);
    }
    }这里
    a(非final)、v1(final)和v2(非final)
    是不同的引用,虽然指向同一内存
    所以v1只是在
    funValueFinal中是final量,标明它不能改变它的值,即地址不能被改变,不能再指向其他对象,不是说指向的对象内容不能变,同时对a和v2是没有影响的。如果:
    class Value {
    int val = 0;
    }
    public class FinalArgument{
    public static void funValue(Value v2){
    // v2 = new Value();
    ++v2.val;
    }
    public static void funValueFinal(final Value v1){
    //!v1 = new Value();
                      v1.val++;
    funValue(v1);
    }
    public static void main(String[] args){
    Value a =new Value();
    System.out.println("a.val="+a.val);
    funValueFinal(a);
    System.out.println("a.val="+a.val);
    }
    }
    则a.val值也是会变的(为2)。
      

  6.   

    另外说明一下
    你可以通过
    System.out.println(v.toString());
    看一下
    虽然v2改变了,但并不影响v1的改变,所以
    funValueFinal(final Value v){
        funValue(v);  //这个绝对有可能使v指向新的对象,这不是和final矛盾了吗???
    }
    此话不对,v不会指向新对象。
      

  7.   

    我下午想了想,终于弄明白了,最近我会把它写出来,在我的Blog上。不管怎么说还是谢谢大家的参与。