通过引用/值传递 - 简单的例子

时间:2012-07-11 16:40:35

标签: java

我知道这个问题已经解决了很多次 - 但是我的Java / C ++知识太弱了我几乎无法理解答案:-( ...我真正喜欢的只是一个非常简单的例子。

在C ++中,我可以编写以下内容:

void func()
{
  int x = 3;
  add_one(x);
  // now x is 4.
}
void add_one(int &var)
{
  var++;
}

我现在想看到的是用java实现相同效果的最简单方法。

6 个答案:

答案 0 :(得分:9)

你不能直接。你可以得到的最接近的是将值放在一个对象中,并将引用(按值,因此引用被复制)传递给方法。

void func()
{
  int x = 3;
  int[] holder = [x];
  add_one(holder);
  // now holder[0] is 4.  x is still 3.
}

// container here is a copy of the reference holder in the calling scope.
// both container and holder point to the same underlying array object
void add_one(int[] container)
{
    container[0]++;
}

这里我使用数组,但包装器可以是任何对象。

答案 1 :(得分:3)

在java方法中,参数是按值传递,并且不能在函数中更改。您必须将int或任何其他基本类型包装在Object或数组中。将Object或数组作为方法参数传递可传递可用于修改对象的引用。

Java已经有基于对象的原始类型的包装器,例如Integer,但这些都是设计不变的。有些库提供了mutable versions这些包装器;你也可以创建自己的:

public class MutableInt
{
    private int val;

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

    public void setValue(int newVal)
    {
        this.val = newVal;
    }

    public int getValue()
    {
        return this.val;
    }
}

void func()
{
    int x = 3;
    MutableInt wrapper = new MutableInt(x);
    add_one(wrapper);
}

void add_one(MutableInt arg)
{
    arg.setValue(arg.getValue() + 1);
}

答案 2 :(得分:2)

你不能这样做。 Java只是通过值传递。基元是显而易见的,但是为对象传递的东西是引用,而不是对象本身。

答案 3 :(得分:0)

从其他答案中可以看出,Java纯粹是通过价值传递的。对象通过一些调用" value-reference"来传递。由于java中的对象只是一个指针引用,你可以想到"值"作为对象存在于堆上的地址。因此,当您进行方法调用时,您将"值",又名地址复制到方法参数:

Object x = new Object();
foo(x);

在对象创建期间

堆 - >分配对象(5000)

变量声明

堆叠 - >分配局部变量(1000)

变量分配

堆栈地址1000设置为5000(指向对象实例)

所以你可以看到这里有两个独立的内存分配。 "值"变量被认为是它在堆上的地址。

方法调用

堆叠 - >分配方法参数8000

堆栈地址8000设置为与传递参数5000相同的值

这就是为什么如果在方法中重新分配对象实例,它不会传播回调用者。您可能已经更改了堆栈位置8000处的堆位置。并且调用方法的堆栈位置1000仍然具有值5000(原始对象实例)。

在C中考虑这个:

void method(myobject * obj);

您当然可以更改" obj"的字段,您可以在本地执行此操作:

obj = new myobject();

但调用者仍会看到它传递的原始值。

Java与& amp;参考运算符。

并且有内置的类可以用于您的目的。 AtomicInteger,AtomicLong等等都是可变的,但是由于涉及同步,你可能会受到性能损失。

我建议使用通用的ValueHolder类来解决您想要模拟传递的所有情况:

public class ValueHolder<T> {
    private T value;
    // getter/setter/constructor
}

答案 4 :(得分:-2)

public int getOneMore(int val) {
  return val + 1;
}

答案 5 :(得分:-3)

Java允许通过引用复制对象,并通过vlaue复制原始类型(int,float等)。默认情况下是这样,不会有任何变化。如果需要更改函数内部的int值,则可以使用类Integer作为示例