Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用与C++;Java中的引用参数?_Java_C++_Reference - Fatal编程技术网

如何使用与C++;Java中的引用参数?

如何使用与C++;Java中的引用参数?,java,c++,reference,Java,C++,Reference,假设我在C++中有这个: void test(int &i, int &j) { ++i; ++j; } 这些值在函数内部更改,然后在外部使用。我怎样才能在Java中编写一个同样的代码?我想我可以返回一个封装两个值的类,但看起来确实很麻烦。 java没有C++引用的等价物。实现此功能的唯一方法是将值封装在另一个类中,并在该类中交换值 关于这个问题,这里有一个冗长的讨论:嗯,有两个解决办法。你自己也提到过。另一个是: public void test(int[]

假设我在C++中有这个:

void test(int &i, int &j)
{
    ++i;
    ++j;
}

这些值在函数内部更改,然后在外部使用。我怎样才能在Java中编写一个同样的代码?我想我可以返回一个封装两个值的类,但看起来确实很麻烦。

java没有C++引用的等价物。实现此功能的唯一方法是将值封装在另一个类中,并在该类中交换值


关于这个问题,这里有一个冗长的讨论:

嗯,有两个解决办法。你自己也提到过。另一个是:

public void test(int[] values) {
    ++values[0];
    ++values[1];
}

不过,我会选择自定义对象。这是一种更干净的方式。另外,尝试重新安排您的问题,以便单个方法不需要返回两个值。

Java没有按引用传递。您必须封装以实现所需的功能。Jon Skeet简要介绍了为何Java中不包含pass-by-reference。

您可以构造装箱对象,即

Integer iObj = new Integer(i);
Integer jObj = new Integer(j);
把你的日常工作写成

public void test(Integer i, Integer j){
  i = i.add(1);
  j = j.add(1);
}
无论出于何种原因,Java的设计者都觉得按值调用更好;它们故意不包含引用调用的方法。(严格地说,它们将引用的副本传递给对象,对于原语类型,它们的特殊情况是纯粹按值调用。但效果是一样的。)

您必须以某种方式将其装箱

整数是不可变的。真没用。 int是可变的,但由于java是按值传递的,所以在这种情况下它也不可用。 有关更多说明,请参见以下页面:和

apachecommons lang有一个MutableInt类。或者你可以自己写

无论如何,它不应该那么糟糕,因为它不应该经常发生。如果确实如此,那么您应该明确地改变用Java编写代码的方式。

使用包装器模拟引用。 一种模拟这种行为的方法是创建一个通用包装器

public class _<E> {
    E ref;
    public _( E e ){
        ref = e;
    }
    public E g() { return ref; }
    public void s( E e ){ this.ref = e; }

    public String toString() {
        return ref.toString();
    }
}
公共类\u{
E参考;
公众(E){
ref=e;
}
public E g(){return ref;}
公共空间s(E E){this.ref=E;}
公共字符串toString(){
返回ref.toString();
}
}
我不太相信这段代码的价值,因为我无法控制它,我不得不编写它:)

就是这样

示例用法:

public class Test {

    public static void main ( String [] args ) {
        _<Integer> iByRef = new _<Integer>( 1 );
        addOne( iByRef );
        System.out.println( iByRef ); // prints 2

        _<String> sByRef = new _<String>( "Hola" );
        reverse( sByRef ); 
        System.out.println( sByRef ); // prints aloH

    }

    // Change the value of ref by adding 1
    public static void addOne( _<Integer> ref ) { 
        int i = ref.g();
        ref.s( ++i  );

        // or 
        //int i = ref.g();
        //ref.s( i + 1 );

    }
    // Reverse the vale of a string.
    public static void reverse( _<String> otherRef ) { 
        String v = otherRef.g();
        String reversed = new StringBuilder( v ).reverse().toString();
        otherRef.s( reversed );
    }

}
公共类测试{
公共静态void main(字符串[]args){
_iByRef=new u1;
addOne(iByRef);
System.out.println(iByRef);//打印2
_sByRef=新的(Hola);
反向(sByRef);
System.out.println(sByRef);//单独打印
}
//通过添加1更改ref的值
公共静态void addOne(ref){
int i=参考g();
参考s(++i);
//或
//int i=参考g();
//参考s(i+1);
}
//倒转绳子的长度。
公共静态无效反向(otherRef){
字符串v=otherRef.g();
字符串反转=新的StringBuilder(v).reverse().toString();
其他参考(反向);
}
}
这里有趣的是,通用包装器类名是“_”,这是一个有效的类标识符。因此,声明如下:

对于整数:

_<Integer> iByRef = new _<Integer>( 1 );
\uibyref=new(1);
对于字符串:

_<String> sByRef = new _<String>( "Hola" );
\usbyref=new(“Hola”);
任何其他课程

_<Employee> employee = new _<Employee>( Employee.byId(123) );
\uemployee=new(employee.byId(123));

方法“s”和“g”代表set和get:p

一个更好的问题:为什么要创建具有这种副作用的方法


通常,这强烈表明您应该将数据提取到一个单独的类中,并使用公共访问器描述操作发生的原因。

这两个整数相关吗?比如一对x/y坐标?如果是这样,我将把整数放在一个新类中,并将该类传递到方法中

class A{ 
  public void test(Coord c)
  {
    c.x++;
    c.y++;
  }
  private class Coord{
    public int x, y;
  }
}

如果这两个整数不相关,您可能需要考虑一下为什么首先要将它们传递到同一个方法中。

尽管这是一种糟糕的设计模式,但另一种可能的解决方案是

static void test(AtomicInteger i, AtomicInteger j)
{
    i.incrementAndGet();
    j.incrementAndGet();
}

最简单的解决方案是使用不需要自己编写的类。

Java按值传递参数,并且没有允许按引用传递的机制。

这仍然不会更改方法外的对象,因为整数是不可变的。你从哪里知道Integer有一个add()方法?总之,正如Bombe指出的那样,整数是不可变的,这就给你留下了完全相同的问题(但需要更多的输入);他是添加这些方法的人。你可以改为传入AtomicInteger,这是可变的。这不是它的预期目的,但几乎可以让这个方法工作。这不起作用,因为对象引用是按值传递的,就像java中的一切一样。读这个。Java只传递对象引用。您可以认为它们本质上与boost shared_ptr相同。只需将基本体框入对象中,即可设置。你可能想更正你问题的措辞。对不起,我必须插话。C++中的引用引用参数是邪恶的。不要这样做。@Steve Lacey-为什么他们是邪恶的?