首页 > 解决方案 > 在 void 方法之后更新 Java 变量

问题描述

我对 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

现在我在看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,函数中gridnumIslands()都会更新。

为什么这与我的第一个示例不同?一个是通过引用传递,另一个是通过值传递吗?

标签: javamethodsparameter-passingpass-by-referencepass-by-value

解决方案


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

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

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

“按引用传递”意味着该方法可以更改调用者的变量以指向不同的对象。这是不可能的。在您的示例中,您可以确定 eggrid不是突然null发生的,或者它的长度发生了变化。


推荐阅读