java传值问题?

public class Demo{
    public static void main(String[] args) {
        int a = 1;
        Integer b = new Integer(1);
        Method1(a, b);
        System.out.println(a);
        System.out.println(b);

    }

    public static void Method1(int a, Integer b) {
        a = 1000;
        b = 1000;
    }
}

我理解a的值不会变,但是为什么b的值也不变呢?

阅读 2.1k
4 个回答

传参等同于赋值,原代码等同于

public class Demo {

    public static void main(String[] args) {
        int a = 1;
        Integer b = new Integer(1);
        
        int _a = a;
        Integer _b = b;
        _a = 1000;
        _b = 1000;
        
        System.out.println(a);
        System.out.println(b);
    }

}

修改的是 _a_b 这两个参数,ab 不受影响

所以 java 无法在方法里修改外部的局部变量,代替的做法是:修改数组元素、对象属性、类属性

public class Demo {
    
    static int c;

    public static void main(String[] args) {
        int[] a = new int[] { 1 };
        MutableInt b = new MutableInt(1);
        c = 1;
        Method1(a, b);
        System.out.println(a[0]);
        System.out.println(b.value);
        System.out.println(c);
    }

    public static void Method1(int[] a, MutableInt b) {
        a[0] = 1000;
        b.value = 1000;
        c = 1000;
    }

}

class MutableInt {

    int value;

    public MutableInt(int value) {
        this.value = value;
    }

}

因为你重新赋值了……


我觉得你是混淆了“按引用传递”和“传递引用”两个概念。

“按引用传递”(Parameter Passing by Ref)和“按值传递”(Parameter Passing by Value)是一对儿,但 Java 中只有按值传递

“传递引用”是说这个参数是个引用类型,但跟它是按什么传递,没有关系。


以隔壁有按引用传递的 C# 为例(拿 C# 为例因为语法跟 Java 比较接近,你应该能看懂):

class Model {
   public int Id { get; set; }
}

public static void Main() {
    int n1 = 1;
    int n2 = 1;
    Model m1 = new Model() { Id = 1 };
    Model m2 = new Model() { Id = 1 };
    Model m3 = new Model() { Id = 1 };
    
    FooPassByValue(n1);
    FooPassByRef(ref n2);
    FooPassByValue_Remalloc(m1);
    FooPassByValue_ModifyPropertyOnly(m2);
    FooPassByRef(ref m3);

    Console.WriteLine(n1);    // 1
    Console.WriteLine(n2);    // 3
    Console.WriteLine(m1.Id); // 1
    Console.WriteLine(m2.Id); // 2
    Console.WriteLine(m3.Id); // 3
}

public static void FooPassByValue(int i) {
    i = 2;
}

public static void FooPassByRef(ref int i) {
    i = 3;
}

public static void FooPassByValue_Remalloc(Model model) {
    model = new Model() { Id = 2 };
}

public static void FooPassByValue_ModifyPropertyOnly(Model model) {
    model.Id = 2;
}

public static void FooPassByRef(ref Model model) {
    model = new Model() { Id = 3 };
}

main 的 b 与 Method1 的 b 是两个不同的变量。它们是 Integer 类型,最初存储同一个对象的引用。

然后, b=1000 使得 Method1 的 b 存储了另一个 Integer 对象的引用。但是这一赋值并不影响 main 中的 b 引用的对象。

新手上路,请多包涵

基本数据类型的参数传递本质是参数值创建一个副本给方法的形参,无论副本怎么改变,都不会影响到原件本身。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏