如何在Java中按引用传递?

huangapple go评论76阅读模式
英文:

How to pass by reference in Java?

问题

我对Java非常新,我在C++和Python方面有相当丰富的经验。现在,从C++转过来,我有点想念按引用传递的功能。我为我想采取的方法编写了代码:

package bs;

public class Main{

    private int a = 1;
    private int b = 11;

    public void inc(int i){
        if (i < 6){
            inc_all(this.a);
        }
        else{
            inc_all(this.b);
        }
    }

    private void inc_all(int prop){
        prop++;
    }

    public void display(){
        System.out.println(a + " " + b);
    }

    public static void main(String[] args){
        Main car = new Main();
        int i = 1;
        while( i < 11){
            car.inc(i);

            car.display();
            i++; 
        }
    }
}

现在,我可以为增加a、b编写两个不同的函数,但我想只编写一个函数,并根据情况传递属性(ab)。在这种情况下,属性明显没有得到增加(感谢按值传递)。如何在不将ab变成数组的情况下解决这个问题(我知道数组始终是按引用传递的)?

英文:

I'm very new to Java, I had decent experience with C++ and Python. Now, coming from C++, I miss pass by reference a bit. I wrote code for the approach I want to take:

package bs;

public class Main{

    private int a = 1;
    private int b = 11;

    public void inc(int i){
        if (i &lt; 6){
            inc_all(this.a);
        }
        else{
            inc_all(this.b);
        }
    }

    private void inc_all(int prop){
        prop++;
    }

    public void display(){
        System.out.println(a + &quot; &quot; + b);
    }

    public static void main(String[] args){
        Main car = new Main();
        int i = 1;
        while( i &lt; 11){
            car.inc(i);

            car.display();
            i++; 
        }
    }
}

Now, I can write two different functions for incrementing a, b, but I want to write only function and pass the the attribute(a or b) depending on the scenario. In this case, the attributes are clearly not getting incremented (thanks to pass by value).

How do I solve this problem without making a and b arrays (I know arrays are always pass by reference)?

答案1

得分: 4

你不能。就是这样。这是Java的特性;这是有意为之。

一般情况下,你应该编写代码,使调用者不能改变事物,而且这是可以的。例如,不要写成:

/** 调用此方法后,`prop` 已经被递增 */
public void increment(int prop) {
    // 在Java中无法编写这个方法。
}

你应该写成:

/** 返回紧随其后的数字域中的值{@code prop}。 */
public int increment(int prop) {
    return prop + 1;
}

如果你希望方法能够进行更改,而调用者可以看到这些更改,你必须传递对于不可变对象的引用:

AtomicInteger x = new AtomicInteger(5);
increment(x);
System.out.println(x.get()); // 这将打印出 '6';

public void increment(AtomicInteger x) {
    x.incrementAndGet();
}

这里的区别在于AtomicInteger是可变的,而原始的整数不是。如果你使用x.,就像开车去房子的地址(x是一个房子的地址,不是房子本身!),进入并对其进行操作。而使用x =,就像对你电话里听到的地址做出更改一样。这对于房子或者打电话告诉你地址的人的地址簿没有任何实质性的影响 - 它只改变了你可以看到的东西(你 = 方法),仅此而已。所以,如果你想让更改可见,要考虑使用点号(或数组括号),而不要使用=

英文:

You cannot. Period. That's a java thing; it's intentional.

In general you should program such that callers cannot change things and that this is fine. For example, instead of:

/** After calling this, `prop` has been incremented */
public void increment(int prop) {
    // this method cannot be written in java, at all.
}

you should have:

/** Returns the value that immediately follows {@code prop} in its numeric domain. */
public int increment(int prop) {
    return prop + 1;
}

If you want methods to be able to make changes that callers can witness, you must pass references to non-immutable objects, instead:

AtomicInteger x = new AtomicInteger(5);
increment(x);
System.out.println(x.get()); // this prints &#39;6&#39;

public void increment(AtomicInteger x) {
    x.incrementAndGet();
}

The difference here is that AtomicInteger is mutable, whereas raw ints are not. If you use x., you are driving over to the house (x is an address to a house, not a house!), entering, and messing with it. With x = , you are making changes to the note upon which you scribbled down the address someone told you over the phone. This has no effect whatsoever on either the house, or the address book of the person who phoned you up to tell you the address - it changes only things you can see (you = method), nothing more. So, if you want changes to be visible, think dots (or array brackets), don't use =.

huangapple
  • 本文由 发表于 2020年10月27日 18:30:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/64552516.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定