避免在Java中传递引用的方法

时间:2014-12-02 14:06:15

标签: java reference porting

这个问题可能和山丘一样古老。然而,在阅读了大量文章和论坛后,我仍然看不到解决问题的好方法。

我必须将一些蒙特卡罗模拟程序从C ++转移到Java。问题是它严重依赖于在函数中通过引用传递变量,例如:

void make_step(int &a, int &b, double &c) {
   a++;
   b += a;
   c *= 1.1;
}

Java中没有通过引用传递,以及可能的类似物,如多个返回值或嵌套函数。我在本网站上阅读的解决方案通常涉及将原始类型封装到对象中。或者 - 将函数分解为单返回函数。但是,在我的情况下,它导致代码太长而且复杂(几行C ++代码几乎增长到Java中的页面)。此外,由于这些算法很难调试,我希望在移植时避免代码的剧烈变化。

我现在所做的是用长度为1的数组替换所有原始类型变量(它们是对象,可以在函数内修改)。但它看起来不是非常优雅的解决方案。有没有人有更好的想法?

5 个答案:

答案 0 :(得分:3)

如果您希望参数是“in-out”变量,则它们必须是对象引用。

使用Mutable Wrappers

您可以使用可变包装器,但这需要您稍微修改现有代码(算法):

class Int {
    int v;
}

class MDouble {
    double v;
}

void make_step(Int a, Int b, MDouble c) {
    a.v++;
    b.v += a.v;
    c.v *= 1.1;
}

使用本地变量副本

如果要保留原始代码,可以创建包装参数的局部变量副本,并且可以使用它们而无需修改代码。

在方法结束时(在return之前)将局部变量复制到包装器中,然后就完成了。这样做的一个提示是使用 try-finally 块,这样无论方法返回的方式和位置如何,都会将局部变量复制回包装器中:

void make_step(int[] aa, int[] bb, double[] cc) {
    int a = aa[0];
    int b = bb[0];
    double c = cc[0];

    try {
        // all your original code comes here
        a++;
        b += a;
        c *= 1.1;
    } finally {
        aa[0] = a;
        bb[0] = b;
        cc[0] = c;
    }
}

答案 1 :(得分:1)

有可变的Integer和Decimal类,你可以使用它们通过引用传递。查看Apache Commons库here

答案 2 :(得分:1)

选项很少:

  • 包装对象中的所有参数。简单版本确实使程序更长,但如果你可以将整个算法包装在一个对象中,那么这些参数就会成为对象成员。
  • 使用可变整数(对象) - 具有get()/ set()方法的Java的AtomicInteger,或者commnos-lang版本

答案 3 :(得分:0)

从c ++编写相同的逻辑到java 更多关于.equals和比较器超过==><比较 使用成员变量和局部变量将更新的对象返回到被调用的方法以获取更改。

答案 4 :(得分:0)

您可以使用“原子引用”将对象包装在引用中。

大多数基本类型都有atomicXXX类。除了首先创建它们的开销之外,它们的工作方式与普通引用类似。

长度为1的数组只是一个解决方案,但如果您不喜欢它们的语法或外观,这是我所知道的唯一可以在没有通用重构的情况下模仿相同行为的其他解决方案。