2

这可能是一个基本问题,但我不确定使用什么关键字来搜索它。

是否可以为 Java 中的返回变量赋值,例如:

static int a[] = new int[2];

static int f(int i) {
    return a[i];
}

static void main() {
    f(1) = 0; // <-- this
}

在 C/C++ 中,我可以返回一个指针并稍后为其赋值。由于 Java 与引用一起工作,我希望上面的代码可以工作。我在这里错过了一些重要的 Java 概念吗?

4

8 回答 8

5

即使是引用类型,方法调用也不是变量

但是,这样的事情就可以了:

static MyClass func() {
   return new MyClass();
}

public static void main(String[] args) {
   func().setAttr(null); // change attributes
}
于 2013-01-30T21:58:56.163 回答
0

这是不可能的(参见其他评论),但您可以创建自己的 MutableInteger 类,该类允许修改其值:

public class MutableInteger {
    public int value;
    public MutableInteger(int value) {
        this.value = value;
    }
    public MutableInteger() {
        this(0);
    }
}

static MutableInteger a[] = new MutableInteger[2];
static {
    for (int i=0; i<a.length; i++) {
        a[i] = new MutableInteger();
    }
}

static MutableInteger f(int i) {
    return a[i];
}

static void main() {
    f(1).value = 0; // <-- this
}
于 2013-01-30T21:59:38.710 回答
0

不,在 Java 中,只有原始类型(其行为与 C++ 中的行为基本相同)和引用类型。引用类型的行为类似于 C++ 指针和 C++ 引用之间的混合——当您使用 时,它们会自动取消引用.,但=始终会更改引用指向的内容,而不是被引用对象的值。

于 2013-01-30T22:00:34.857 回答
0

这行不通。也许它有助于理解“机器”级别发生的事情。在方法内部f,表达式a[i]被评估为一个int值。返回此 int 值,与与该值关联的数组没有任何连接。从方法返回后,您int在 Java 虚拟机的操作数堆栈上获得了值(将其视为中间值)并且可以用它做一些事情。你可以删除它(如果你写f(1);在一行中会发生这种情况),你可以将它分配给一个变量(int x = f(1)),就是这样。

于 2013-01-30T22:00:53.447 回答
0

一种方法是将数组转换为MutableInts(或AtomicIntegers)的数组,并返回i对该数组的第 -th 元素的引用:

static AtomicInteger a[] = new AtomicInteger[2];
static {
    for (int i = 0; i < a.length; ++i) {
        a[i] = new AtomicInteger(0);
    }
}

static AtomicInteger f(int i) {
    return a[i];
}

public static void main(String[] args) {
    f(1).set(0);
}
于 2013-01-30T22:01:01.677 回答
0

这将是一个编译错误,因为赋值运算符要求左侧是Expression NameField Access ExpressionArray Access Expression,而是f(1)Method Invocation Expression

抛开编译错误不谈,这不是 Java 的工作方式。在 Java 中,一切都是按值传递的——尤其是在这个特定的示例中,因为您的返回类型是int.

static /*RETURN TYPE IS PRIMITIVE VALUE:*/ int f(int i) {
    return a[i];
}

如果我们添加一个中间变量,它会变得更清晰:

static /*RETURN TYPE IS PRIMITIVE VALUE:*/ int f(int i) {
    int ret = a[i]; // ret is an independent value from a[i]
                    // it and a[i] can be changed without affecting each other
    return return ret;
}
于 2013-01-30T22:15:13.437 回答
0

OP的问题是

是否可以为Java中的返回变量赋值

非常简单...(注意我分配 10 以显示证明,因为在初始化的 int 数组中所有值都是 0)...

static int a[] = new int[2];

static int f(int[] p, int index, int val) {
    return p[index] = val;
}

static void main() {        
    // f(a, 1, 0); use 10 (below) so we can show proof
    f(a, 1, 10);
    // proof
    System.out.println(a[1]);
}

另一个例子......很傻,但有效......

static int a[] = new int[2];

static int[] f(int[] p) {
    return p;
}

static void main() {
    f(a)[1] = 10;
}

完后还有 ...

static int a[] = new int[2];

static void f(int i, int val) {
    a[i] = val;
    return;
}

static void main() {
    f(1, 10);
}
于 2013-01-30T23:21:06.513 回答
0

您可能对如何将 lambdas 应用于此问题感兴趣,尽管这只适用于 Java 8 预览版。

假设在标准库中有这样定义的接口:

interface Block<T> {
    void accept(T v);
}

(有一个建议把它放进去java.util.functions,只是增加了一点复杂性......)

现在我们可以这样写你的例子:

// Declare an array
int[] a = new int[5];

// Capture an "assignment reference" to element 2 
Block<Integer> elem2 = v -> a[2] = v;

// Some time later, we want to store a new value in that element:
elem2.accept(360);

所以你的函数会返回Block<Integer>,你以后可以调用accept它来给它一个要存储的值。

于 2013-01-30T23:34:14.717 回答