在void方法之后更新Java变量[duplicate]

问题描述 投票:0回答:2

这个问题在这里已有答案:

我对Java如何工作有点困惑,我知道以下是真的:

public static void main(String[] args) {
    int c=0;
    changeC(c);
    System.out.println(c); // 0
}

public static void changeC(int c) {
    c++;
}

我们知道c输出0因为changeC方法不改变原来的c

现在我正在看一个solution on Leetcode,它似乎遵循类似的概念。

这是代码:

public int numIslands(char[][] grid) {
    int count=0;
    for(int i=0;i<grid.length;i++)
        for(int j=0;j<grid[0].length;j++){
            if(grid[i][j]=='1'){
                dfsFill(grid,i,j);
                count++;
            }
        }
    return count;
}
private void dfsFill(char[][] grid,int i, int j){
    if(i>=0 && j>=0 && i<grid.length && j<grid[0].length&&grid[i][j]=='1'){
        grid[i][j]='0';
        dfsFill(grid, i + 1, j);
        dfsFill(grid, i - 1, j);
        dfsFill(grid, i, j + 1);
        dfsFill(grid, i, j - 1);
    }
}

在这种情况下,网格传递给void函数dfsFills()。然而,无论dfsFill()grid做什么,grid函数中的numIslands()也会更新。

为什么这与我的第一个例子不同?一个通过引用传递而另一个通过值传递?

java methods parameter-passing pass-by-reference pass-by-value
2个回答
1
投票

它不是通过引用传递的,因为无论方法内部发生了什么,调用者的变量grid仍然指向它在调用之前所做的相同对象。

区别在于grid是一个可变对象(数组),因此该方法可以导致grid内部的状态发生变化。由于两个地方(调用者和被调用者)都看同一个对象,他们都会看到那里所做的更改。

Java中的所有内容都是按值传递的。但是除了原始类型之外,传递“值”的是指向对象的指针。因此,如果该对象的状态是可变的,则需要小心。

“传递引用”意味着该方法可以将调用者的变量更改为指向不同的对象。这是不可能的。在您的示例中,您可以确定例如grid不是突然null或其长度已经改变。


0
投票

是的,不是。

是的,因为这是JVM内部工作的方式。像int这样的原始参数是通过复制它们的值来传递的,而所有其他参数如Stringint[]都是通过复制引用(指向堆中的实际对象)来传递的。

不,因为你会看到完全相同的行为,即使你正在使用java.lang.Integer,这是盒装类型的int并通过复制引用传递。实际上,java中根本没有使用像“pass by value”和“pass by ref”这样的术语。

void foo() {
  Integer i = 0;
  bar(i);
  assert i == 0;
}

void bar(Integer i) {
  i++;
}

关键的事实是i++意味着i = i + 1,它使用i1产生一个新的int,绑定名称i与新的int,并丢弃以前的int值,而不是直接改变以前的int

array[0]++people.age++这样的东西以同样的方式工作。它将age的属性people与新的int绑定。它改变了属性age,但不影响int本身

© www.soinside.com 2019 - 2024. All rights reserved.