【问题标题】:Java primitives in class type parameter passing类类型参数传递中的 Java 原语
【发布时间】:2011-12-15 04:10:15
【问题描述】:

我知道,如果您将 Class 类型作为方法的参数传递,则指针将被传递,并且如果您在方法中编辑参数,您还将编辑您传递的原始对象实例(例如,如果一个名为 @987654322 的方法@ 执行以下代码:

public void changeColor(Color color)
{
    color = new Color(20, 100, 50);
}

你这样称呼这个值:

Color color = new Color(10, 20, 30);
System.out.println(color.toString());
changeColor(color);
System.out.println(color.toString());

控制台的两行应该是不同的(java.awt.Color[r=10,g=20,b=30]java.awt.Color[r=20,g=100,b=50]),因此改变了值并传递了指针。另一方面,如果你使用 int 值,它是一个原始值,你会得到不同的结果:

public void changeNumber(int i)
{
    i = 10;
}

你这样称呼这个值:

int n = 5;
System.out.println(n);
changeNumber(n);
System.out.println(n);

控制台不打印510,但在两行都显示5。话虽如此,如果我有这个:

public class A
{
    public int i;
    public Color c;

    public A(int n, Color color)
    {
        i = n;
        c = color;
    }
}

在可运行类中...

public static void main(String[] args)
{
    A a = new A(10, new Color(10, 40, 23));
    changeA(a);
}

public static changeA(A varA)
{
    varA.i = 54;
    varA.c = new Color(40, 30, 264)
}

A 类中的 i 是否也会像它是 A 指针的一部分一样,或者如果 main 方法中的 a.i 在我运行 changeA(a) 后没有改变,值是否会改变?如果没有,我该怎么做才能改变它?

【问题讨论】:

  • 这是错误的。传递给changeColor()color 对象不会改变。你真的运行过你的代码吗? Java 按值传递引用。这意味着方法不能导致调用者的引用指向新的东西。

标签: java pointers parameters primitive


【解决方案1】:

您希望在 Java 中通过引用传递。这是不可能的。有关详细信息,请参阅this 问题的答案。

【讨论】:

  • 我不同意call-by-reference。我发现最好将它们称为 all call-by-value(其中对象是 call-by-value-[of-the-reference]),或者我更喜欢将它们称为基元的 call-by-value 和对象的 call-by-object-sharing。请参阅Evaluation strategy 文章。 call-by-reference 意味着不同的语义。 分配给参数变量.
【解决方案2】:

A 类中的 i 是否也会像它是 A 指针的一部分一样,或者如果在我运行 changeA(a) 后主方法中的 a.i 没有改变,值是否会改变

作为参数传递给AA 实例中i 的值将发生变化。

但我不会说它的行为“好像它是 A 的指针的一部分”。对 A 的引用是一个不可变的值。您正在更改它所引用的对象的状态。

顺便说一句,这不是“按引用传递”的意思,它与 C# 和 C++ 等语言中实现的按引用传递或传递变量/成员地址的 C hack 不同/ 随便。

【讨论】:

  • Nit:C++ 和 C# 有按引用调用,而 C 没有。 (传递指针是按值调用。)
【解决方案3】:

这已经解释过很多次了,上面已经解释过两次了,但我喜欢这样解释:

(请注意,我忽略了“内部细节”:我发现讨论语义不需要它们,但他们应该在一天结束时被理解。事实上,我我什至不打算讨论 evaluation strategies used,只是说 Java 使用 call-by-value 并且传递的对象具有 call-by-object-sharing 语义,这是通过将对象的 reference 作为内部传递来实现的值。)

  • 当一个原始值被传递时复制一份。 (尽管这与下一点有些无关,因为原始值无法更改。)

  • 当一个对象被传递(或分配)时,同一个对象被传递(或被分配)。 不会出现对象的副本:除非重新分配相关参数变量,否则将评估与传入的对象相同的对象(或null,也许)。因为一个对象就是它自己,那么在一个位置改变对象——不管它当前有什么“变量名”——改变相同的对象到处。

我想要一个新的、独立的对象,然后创建一个:)

编码愉快。

【讨论】:

    猜你喜欢
    • 2011-01-14
    • 1970-01-01
    • 1970-01-01
    • 2013-02-16
    • 2021-12-17
    • 2020-04-18
    • 2012-11-25
    • 2016-04-25
    • 2021-02-12
    相关资源
    最近更新 更多