public class Test{
   static void Intk(Integer k){
        k++;
   }
   public static void main(String[] args){
      Integer k=new Integer(1);
      Intk(k);
      System.out.print(k);
   }
}为啥出来的是1,传入Inyk的不是k的引用吗?
如果想让k的值+1,函数Intk要怎么写?

解决方案 »

  1.   

     static int Intk(int k){
            ++k;
            System.out.println(k);
    return k;
     } public static void main(String[] args)
    {

    int k=0;
    k= Intk(k);
    System.out.print(k); }
      

  2.   

    楼上的方法我也知道,可是用void不行吗?
      

  3.   

    你跟一下你就明白了啦
    VOID和INT的区别
    你看看你传进的K在Intk方法是加1啦
    但是你main函数里打印的还是你Integer k=new Integer(1);
    所赋的初值
      

  4.   

    关于Java传参:
    1.基本类型为值传递.2.类对象传递其引用的复制.3.String类型以及所有的基本类型的包装类有特殊情况,因为不可变类和常数池的机制,他们的引用改变不了他们所指向的对象的值。只有将改变后的对象作为返回值才能得到改变后的对象。楼主的问题参见第三点.
      

  5.   

    JDK 5引进了很多新的特性,其中有一个就是自动装箱(Autoboxing)和自动拆箱(Auto-Unboxing)。
    在k++的时候就等于k=k+1;
    再翻译为k=Integer.valueOf(Integer.valueOf(k)+1);
    再看看java.lang.Integer中关于valueOf的源代码是怎样的:
    public static Integer valueOf(int i) {
        final int offset = 128;
        if (i >= -128 && i <= 127) { // must cache
          return IntegerCache.cache[i + offset];
        }
        return new Integer(i);
    }
    在这里k就指到了另外的一个对象,所以他的直在改变没有影响到原来的值~`
      

  6.   

    楼主可以用1楼使用返回值的方式.在String类以及包装类中,虽然传递的同样是引用,但是Java不会修改引用指向的对象.
    一旦其值发生改变:
    Java会查找对应的常量池,如果常量池中存在改变后的对象,那么Java会复制一个并将该引用指向复制的那个对象.
    如果常量池不存在改变后的对象,Java会先在池中建立一个,然后再复制一个并将该引用指向复制的那个对象.所以楼主原代码中:
    Intk中的k和main中的k都指向1.
    k++之后,main的k指向1,不过Intk中k的指向被改变,它其实指向一个新的Integer对象2.
    最后打印main中的k,结果当然为1.解决办法如1楼,使用return,覆盖main中的k,使其指向2.
      

  7.   

    要实现,拿个对象包一下就行了
    public class Main { private Integer k; static void Intk(Main m) {
    m.k++;
    } public static void main(String[] args) {
    Main m = new Main();
    m.k = new Integer(1);
    Intk(m);
    System.out.print(m.k);
    }
    }
      

  8.   

    回5楼:
    问题应该和自动装箱无关,我在JDK1.4中测试楼主代码,结果依然是1...
    我认为主要原因还是String和包装类的特殊情况喵~~~~`
      

  9.   

    jdk1.4
    static void Intk(Integer k){
      k++;
    }
    这种写法就报错
    编译都通不过,你的jdk1.4这么强?
      

  10.   

    回10楼,我再44,刚才在Eclipse里选的1.4level.不过新特性不报错.
    不过我坚持k不改变同拆包无关,那几个类特殊而已.它直接改变引用而不改变对象.
      

  11.   


    是啊,LZ 是代码能通过编译啊?我怎么不能通过啊? (Integer) k++ ,这也行??!!~~~ 
      

  12.   

    你就用控制台试试``
    看看字节码就清楚了 public void view() {
    Integer k = new Integer(1);
    k++;
    }
    字节码为:
    public void view();
      Code:
       0:   new     #2; //class java/lang/Integer
       3:   dup
       4:   iconst_1
       5:   invokespecial   #3; //Method java/lang/Integer."<init>":(I)V
       8:   astore_1
       9:   aload_1
       10:  astore_2
       11:  aload_1
       12:  invokevirtual   #4; //Method java/lang/Integer.intValue:()I
       15:  iconst_1
       16:  iadd
       17:  invokestatic    #5; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       20:  dup
       21:  astore_1
       22:  astore_3
       23:  aload_2
       24:  pop
       25:  return
    当中就掉用了Integer.valueOf();
    所以k++是和k=Integer.valueOf(Integer.valueOf(k)+1);效果是一样的。再看看Integer.valueOf的源码`
    ps:jdk1.4会报错说不能从Integer转化为int的,
    1.5版本以下都不能long=Long,int=Integer .... 转
      

  13.   

    呃,考虑1.4的情况例子不好举,1.4的话楼主的代码一定不能通过.
    5楼的例子其实也很明显了,任何妄图改变k值的操作,Java都会new一个新的出来...5楼的解释也很正确...楼主代码之所以没报错,是拆包的缘故,换1.4写的话,楼主就不会有疑惑了.
      

  14.   

    回12楼:
    刚才我在Eclipse里测试的,虽然选了1.4不过有新特性会自动容错.回13楼,同意你的看法,其实正是这些代码体现了不可变类的特点,一旦发生改变,引用将指向新对象.
      

  15.   

    Navigator浏览器居然不支持代码编辑器
      

  16.   

    你从下面的程序可以看出一个究竟
    public class Pass { 
    String a="123"; 
    public static void test(Pass passA) { 
    passA.a="abc"; 

    public static void main(String[] args) { 
    Pass passB=new Pass(); 
    passB.a= "123"; 
    System.out.println(passB.a); 
    test(passB); 
    System.out.println(passB.a); 


    结果是: 
    123 
    abc 所有的参数传递都是 传值,从来没有 传引用 这个事实。 
    所有的参数传递都会在 程序运行栈上 新分配一个 值 的复制品. 如果把
    public static void test(Pass passA) { 
    passA.a="abc"; 
    } 改成
    public static void test(Pass passA) { 
    passA = null; 
    }看看, 对passA有什么影响? 
    毫无作用。函数调用出来后,passA还是原来的值,不会变成Null. 这个传的 PassA 的 地址值。这个 地址值 被复制了一份。 
      

  17.   

    public class Test{
       static void Intk(Integer k){
            k++;
       }
       public static void main(String[] args){
          Integer k=new Integer(1);
          Intk(k);
          System.out.print(k);
       }
    }
    这个程序中也是传入的是Integer k地址值(复制值),而且是复制了一份给Intk()函数,在Intk()里面改变的是Integer k复制值,在函数外面没有改变