使用引用调用交换两个数字

the*_*lip 3 java methods swap pass-by-reference pass-by-value

我们可以使用传递引用或通过引用调用在Java中交换两个数字吗?最近,当我遇到用Java交换两个数字时,我写道

class Swap{
    int a,b;
    void getNos(){
        System.out.println("input nos");
        a = scan.nextInt();
        b = scan.nextInt(); // where scan is object of scanner class
    }
    void swap(){
        int temp;
        temp = this.a;
        this.a = thisb;
        this.b = this.a;
    }
}
Run Code Online (Sandbox Code Playgroud)

在main方法中我调用上面提到的方法并取两个整数a,b然后使用第二个方法我交换两个数字,但相对于对象本身....

该程序或逻辑是否通过引用传递?这是正确的解决方案吗?

MBy*_*ByD 6

是的,不是.Java永远不会通过引用传递,您的方式是一种解决方法.但是你创建一个类来交换两个整数.相反,您可以创建一个int包装器并使用pass it,这样整数可以在不需要时分开:

public class IntWrapper {
    public int value;
}

// Somewhere else
public void swap(IntWrapper a, IntWrapper b) {
    int temp = a.value;
    a.value = b.value;
    b.value = temp;
}
Run Code Online (Sandbox Code Playgroud)

正如评论所示,我可能不够清楚,所以让我详细说明一下.

通过参考传递意味着什么?这意味着当您将参数传递给方法时,您可以在此方法中更改原始参数本身.

例如,如果Java是按引用传递的,则会打印出以下代码x = 1:

public class Example {
    private static void bar(int y) {
        y = 10;
    }
    public static void main(String[] args) {
        int x = 1;
        bar(x);
        System.out.println("x = " + x);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是正如我们所知,它打印0,因为传递给bar方法的参数原始的副本x,并且对它的任何赋值都不会影响x.

以下C程序也是如此:

static void bar(int y) {
    y = 1;
}
int main(int argc, char * argc[]) {
    int x = 0;
    bar(x);
    printf("x = %d\n", x);
}
Run Code Online (Sandbox Code Playgroud)

如果我们想要更改其值x,我们将必须传递其引用(地址),如下例所示,但即使在这种情况下,我们也不会传递实际引用,而是传递引用的副本,并通过解除引用它我们将能够修改x的实际值.然而,直接赋值给引用不会改变引用本身,因为它是通过值传递的:

static void bar(int &y) {
    *y = 1;
    y = NULL;
}
int main(int argc, char * argc[]) {
    int x = 0;
    int * px = &x;
    bar(px);
    printf("x = %d\n", x); // now it will print 1
    printf("px = %p\n", px); // this will still print the original address of x, not 0
}
Run Code Online (Sandbox Code Playgroud)

因此传递变量的地址而不是变量本身解决了C中的问题.但是在Java中,由于我们没有地址,我们需要在我们想要分配它时包装变量.在仅修改对象的情况下,我们没有那个问题,但是,如果我们想要分配它,我们必须包装它,如第一个例子中那样.这不仅适用于原始对象,也适用于对象,包括我刚才提到的那些包装器对象.我将在一个(更长的)示例中显示它:

public class Wrapper {
    int value;
    private static changeValue(Wrapper w) {
        w.value = 1;
    }
    private static assignWrapper(Wrapper w) {
        w = new Wrapper();
        w.value = 2;
    }
    public static void main(String[] args) {
        Wrapper wrapper = new Wrapper();
        wrapper.value = 0;
        changeValue(wrapper);
        System.out.println("wrapper.value = " + wrapper.value); 
        // will print wrapper.value = 1
        assignWrapper(w);
        System.out.println("wrapper.value = " + wrapper.value); 
        // will still print wrapper.value = 1
    }
}
Run Code Online (Sandbox Code Playgroud)

嗯,就是这样,我希望我说清楚(并没有犯太多错误)

  • 在Java中,您不传递对象,您传递引用.甚至`Object o1 = o2`也不是处理对象而是处理引用.所以`f(o1)`也通过值传递引用(与引用传递不同).根据我的经验,任何人都不正确地或者通过引用方式调用这种机制,或者不是真的知道他在说什么,或者试图采用在某些情况下有效但在其他情况下无效的快捷方式. (3认同)
  • 我从未听说过这个词.Java只是不通过引用传递.即使传递了引用(对象引用),也不能在方法中更改引用,只能引用它引用的对象. (2认同)
  • @EserAygün:即使在C/C++中,你的建议也是"按值传递",因为你传递指针而不是对象.只有C++才能支持`swap(int&a,int&b)`引用实际的传递. (2认同)
  • @EserAygün:两点:在机器代码级别上它可能是相同的.但是术语不是基于类似的实现细节,而是基于语言(这里是Java)本身的可见效果.第二:如果语言不支持通过引用传递但支持某种指针(在C中)或某种引用类型(Java),则_you_作为语言的用户可以_simulate_ _some_(并非所有)PBR的效果使用间接.这种手动间接是__不正确___经常被命名为"通过引用传递" - 作为一种语言快捷方式. (2认同)