tipos que programacion long ejemplos ejemplo declarar datos cuadro comparativo java c++ reference

que - ¿Cómo uso un equivalente a los parámetros de referencia de C++ en Java?



tipos de datos en java ejemplos (11)

Supongamos que tengo esto en C ++:

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

Los valores se alteran dentro de la función y luego se usan afuera. ¿Cómo podría escribir un código que haga lo mismo en Java? Me imagino que podría devolver una clase que encapsule ambos valores, pero eso parece realmente engorroso.


Bueno, hay un par de soluciones. Usted mencionó uno usted mismo. Otro sería:

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

Me gustaría ir con el objeto personalizado, sin embargo. Es una forma mucho más limpia. Además, intente reorganizar su problema para que un solo método no tenga que devolver dos valores.


Java no tiene equivalente de referencias de C ++. La única forma de hacer que esto funcione es encapsular los valores en otra clase e intercambiar los valores dentro de la clase.

Aquí hay una larga discusión sobre el tema: http://www.yoda.arachsys.com/java/passing.html


Java no tiene pass-by-reference. Debe encapsular para lograr la funcionalidad deseada. Jon Skeet tiene una breve explicación de por qué el paso por referencia fue excluido de Java.


Podrías construir objetos en caja, es decir,

Integer iObj = new Integer(i); Integer jObj = new Integer(j);

y escribe tu rutina como

public void test(Integer i, Integer j){ i = i.add(1); j = j.add(1); }

Por varias razones, los diseñadores de Java sintieron que el call-by-value era mejor; deliberadamente no incluyeron un método para llamar por referencia. (Estrictamente, pasan copias de referencias a los objetos, con el caso especial para los tipos primitivos que son puramente llamados por valor. Pero el efecto es el mismo).


Tienes que boxear (a tu manera) de alguna manera.

El entero es inmutable. tan inútil. int es mutable pero dado que java pasa por valor, entonces no se puede usar de nuevo en ese caso. Consulte estas páginas para obtener más explicaciones: ¡ Java es Pass-by-Value, Dammit! y int vs Integer

Apache commons lang tiene una clase MutableInt. O podrías escribirlo tú mismo.

En cualquier caso, no debería ser tan malo porque no debería suceder a menudo. Si lo hace, entonces definitivamente debería cambiar la forma en que codifica en Java.


Una mejor pregunta: ¿por qué estás creando métodos con tales efectos secundarios?

En general, esta es una fuerte indicación de que debe extraer los datos en una clase separada, con accesodores públicos que describan por qué se está llevando a cabo la operación.


¿Están los dos enteros relacionados? ¿Como un par de coordenadas x / y? De ser así, colocaría los enteros en una nueva clase y pasaría esa clase al método.

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

Si los dos enteros no están relacionados, es posible que desee pensar por qué los está pasando en el mismo método en primer lugar.


Aunque es un mal diseño de patrón en mi humilde opinión, otra posible solución es

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


Simulando referencia con envoltorios.

Una forma en que puede simular de alguna manera este comportamiento es crear un contenedor genérico.

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(); } }

No estoy muy convencido sobre el valor de este código, no pude evitarlo, tuve que codificarlo :)

Asi que aqui esta.

El uso de muestra:

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 ); } }

Lo divertido aquí, es que el nombre genérico de la clase contenedora es "_", que es un identificador de clase válido. Entonces una declaración dice:

Para un entero:

_<Integer> iByRef = new _<Integer>( 1 );

Para una cadena:

_<String> sByRef = new _<String>( "Hola" );

Para cualquier otra clase

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

Los métodos "s" y "g" significan establecer y obtener: P



Java pasa los parámetros por valor, y no tiene ningún mecanismo para permitir pasar por referencia.