代码之家  ›  专栏  ›  技术社区  ›  cchampion

如何从另一个方法在java中增加类整数引用值

  •  26
  • cchampion  · 技术社区  · 15 年前
    package myintergertest;
    
    /**
     *
     * @author Engineering
     */
    public class Main {
    
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            //this one does not increment 
            Integer n = new Integer(0);
            System.out.println("n=" + n);
            Increment(n);
            System.out.println("n=" + n);
            Increment(n);
            System.out.println("n=" + n);
            Increment(n);
            System.out.println("n=" + n);
            Increment(n);
    
            //this one will increment
            MyIntegerObj myInt = new MyIntegerObj(1);
            Increment(myInt);
            System.out.println("myint = " + myInt.get());
            Increment(myInt);
            System.out.println("myint = " + myInt.get());
            Increment(myInt);
            System.out.println("myint = " + myInt.get());
    
        }
    
        public static void Increment(Integer n) {
            //NO.  this doesn't work because a new reference is being assigned
            //and references are passed by value in java
            n++;
        }
    
        public static void Increment(MyIntegerObj n) {
            //this works because we're still operating on the same object
            //no new reference was assigned to n here.
            n.plusplus();   //I didn't know how to implement a ++ operator...
        }
    }
    

    所有这些的结果都是n=0。整数n是一个对象,因此通过引用传递,那么为什么增量没有反映回调用方方法(main)中呢?我期望输出为n=0 n=1 n=2等。。。

    这听起来像是我理解正确了吗?

    10 回复  |  直到 15 年前
        1
  •  39
  •   Jon Skeet    12 年前

    不,对象不是通过引用传递的。引用是按值传递的,这有很大的区别。 Integer

    你的 n++; 声明是有效的

    n = Integer.valueOf(n.intValue() + 1);
    

    n 在里面 Increment -但是作为Java 只有 具有传递值,这不会影响的值 在调用方法中。

    编辑:回答你的更新:没错。假设您的“MyIntegerObj”类型是可变的,并且在调用时更改其内部状态 plusplus() . 哦,不要到处寻找如何实现操作符——Java不支持用户定义的操作符。

        2
  •  24
  •   DerMike Vladimír Schäfer    15 年前

    AtomicInteger 从…起 java.util.concurrent.atomic . 它有一个“incrementAndGet”方法,适合您的showcase。

        3
  •  8
  •   Itay Maman    15 年前

    这种类型的行为通常通过将方法从void更改为int(在本例中为int)来实现: public static int increment(int n) { return ++n; }

    或者,也可以将整数包装在泛型单元格类中。您只需编写此单元类一次:

    public class Cell<T> {
      public Cell(T t) { value = t; }
      public void set(T t) { value = t; }
      public T get() { return value; }
    }
    

    public static void increment(Cell<Integer> n) {
      n.set(n.get()++);
    }
    
    Cell<Integer> n = new Cell<Integer>(0);
    increment(n);
    increment(n);
    increment(n);
    System.out.println(n.get()); // Output: 3
    
        4
  •  3
  •   danben    15 年前

    正如Jon Skeet提到的,Java中的所有方法都是按值传递的,而不是按引用传递的。由于引用类型是按值传递的,所以函数体中的引用是引用的副本-此副本和原始引用都指向相同的值。

    但是,如果在函数体内部重新分配副本,则不会对程序的其余部分产生影响,因为当函数退出时,副本将超出范围。

    但是,考虑到你并不真的需要通过参考来做你想做的事情。例如,您不需要方法来增加 Integer -您可以在代码中需要递增的点处递增它。

    对于更复杂的类型,如在对象上设置某些属性,您正在使用的对象可能是可变的;在这种情况下,引用的副本工作得很好,因为自动取消引用将使您到达正在调用其setter的原始对象。

        5
  •  3
  •   Jay    5 年前

    旁注:以我的拙见,在整数对象上编写n++是极其误导的。这依赖于Java的一个称为“自动装箱”的功能,在该功能中,它会自动且无警告地将原语转换为相应的装箱对象,如int到Integer或boolean到boolean。坦率地说,我认为这是一个糟糕的特性。是的,有时它会自动为你做一个方便的转换,从而使你的生活变得更简单,但它也可以做一些你不打算也没有意识到正在发生的转换,产生意想不到的副作用。

    第一:让增量函数返回一个新的整数和更新后的值。比如:

       public Integer increment(Integer n)
        {
          Integer nPlus=Integer.valueOf(n.intValue()+1);
          return nPlus;
        }
    

    Integer n=Integer.valueOf(0);
    n=increment(n); // now n==1
    n=increment(n); // now n==2
    

    第二:创建自己的类,该类类似于Integer,但它是可变的。比如:

    class MutableInteger
    {
      int value;
      public MutableInteger(int n)
      {
        value=n;
      }
      public void increment()
      {
        ++value;
      }
      ... whatever other functions you need ...
    }
    

    当然,最大的问题是您几乎必须重新发明Integer类。

        6
  •  2
  •   Joe    15 年前

    你不能。Java严格按值传递。

    看见 http://javadude.com/articles/passbyvalue.htm

    哪一个更好取决于情况。

        7
  •  2
  •   JareQ    14 年前

    皮肤样

    public void doStuff() {
      AtomicInteger i = new AtomicInteger(0);
      increment(i);
      System.out.println(i);
     }
    
      public void increment(AtomicInteger i) {
        i.set(i.get() + 1);
     }
    
        8
  •  1
  •   Kevin    15 年前

    Integer 是一个 value object 这意味着这是一个无法改变的价值。

    注意 n++ 相当于 n = n + 1 . 您只是在更改局部变量引用的值 n ,而不是 N

        9
  •  1
  •   cjaniake    11 年前

    见原子整数: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicInteger.html

    您可以使用这个java.util.concurrent类实现线程安全。

        10
  •  0
  •   Suraj Rao Raas Masood    6 年前
    public class passByReferenceExample {
        static void incrementIt(Long b[]){
            Long c = b[0];
            c=c+1;
            b[0]=c;
    
        }
        public static void main(String[] args) {
            Long a[]={1L};  
    
            System.out.println("Before calling IncrementIt() : " + a[0]);
            System.out.println();
            incrementIt(a);
            System.out.println("after first call to incrementIt() : " + a[0]);
            incrementIt(a);
            System.out.println("after second call to incrementIt(): "+ a[0]);
            incrementIt(a);
            System.out.println("after third call to incrementIt() : "+ a[0]);
            incrementIt(a);
            System.out.println("after fourth  call to incrementIt(): "+ a[0]);    
        }
    }
    

    输出:

    Before calling IncrementIt() : 1
    
    after first call to incrementIt() : 2
    after second call to incrementIt(): 3
    after third call to incrementIt() : 4
    after fourth  call to incrementIt(): 5