¿Cómo puedo pasar un tipo primitivo por referencia en java? Por ejemplo, ¿cómo puedo hacer que un int
pase a un método modificable?¿Cómo paso un tipo de datos primitivo por referencia?
Respuesta
No hay una forma de pasar una primitiva directamente por referencia en Java.
Una solución alternativa es pasar una referencia a una instancia de una clase contenedora, que a continuación contiene la primitiva como un campo miembro. Tal clase de contenedor podría ser extremadamente fácil de escribir por sí mismo:
public class IntRef { public int value; }
Pero ¿qué tal un poco de pre-construidos clases de contenedor, por lo que no tenemos que escribir nuestra propia?OK:
Los Apache commons-lang mutables clases *:
Ventajas: buen rendimiento para el uso de un solo subproceso. Lo completo.
Desventajas: presenta una dependencia de biblioteca de terceros. Sin controles de simultaneidad incorporados.
Clases representativas: MutableBoolean, MutableByte, MutableDouble, MutableFloat, MutableInt, MutableLong, MutableObject, MutableShort.
Los java.util.concurrent.atomic atómicos * clases:
Ventajas: parte del estándar de Java (1.5 +) API. Controles de simultaneidad incorporados.
Desventajas: pequeño golpe de rendimiento cuando se utiliza en una configuración de un solo hilo. Falta soporte directo para algunos tipos de datos, p. no hay AtomicShort.
Clases representativas: AtomicBoolean, AtomicInteger, AtomicLong y AtomicReference.
Nota: como usuario ColinD shows in his answer, AtomicReference se puede utilizar para aproximar algunas de las clases que faltan, p. AtomicShort.
Longitud 1 matriz primitiva
OscarRyz's answer muestra el uso de una matriz de longitud 1 de "envolver" un valor primitivo.
Ventajas: Rápido de escribir. Performant. No se necesita una biblioteca de terceros.
Desventajas: Un poco sucio. Sin controles de simultaneidad incorporados. Resultados en un código que no (claramente) se auto-documenta: ¿está la matriz en la firma del método allí para que pueda pasar múltiples valores? ¿O está aquí como andamio para la emulación de paso por referencia?
ver también
Las respuestas a la pregunta StackOverflow "Mutable boolean field in Java".
Mi opinión
En Java, debe esforzarse por utilizar los enfoques anteriores con moderación o no en absoluto. En C, es común usar el valor de retorno de una función para retransmitir un código de estado (SUCCESS/FAILURE), mientras que la salida real de una función se transmite a través de uno o más parámetros de salida. En Java, es mejor usar Excepciones en lugar de códigos de retorno. Esto libera los valores de retorno del método que se utilizarán para transportar la salida del método real, un patrón de diseño que la mayoría de los programadores de Java consideran más natural que los parámetros externos.
Atomics son muy útiles para pasar un contador a una función que se llama varias veces, especialmente si el aumento del contador es condicional en la función, pero no aumentarlo no necesariamente significa que algo falló. De todos modos, gracias por esta respuesta. Es muy útil. – Nyerguds
Eso no es posible en Java
Nothing in java se pasa por referencia. Todo pasó por valor.
Editar: Tanto las primitivas como los tipos de objetos se pasan por valor. Nunca puede alterar el valor/referencia pasado y esperar que cambie el valor/referencia de origen. Ejemplo:
String a;
int b;
doSomething(a, b);
...
public void doSomething(String myA, int myB) {
// whatever I do to "myA" and "myB" here will never ever ever change
// the "a" and "b"
}
La única manera de evitar este obstáculo, independientemente de que sea una primitiva o de referencia, es pasar un objeto contenedor, o utilizar el valor de retorno.
Con un titular:
private class MyStringHolder {
String a;
MyStringHolder(String a) {
this.a = a;
}
}
MyStringHolder holdA = new MyStringHolder("something");
public void doSomething(MyStringHolder holder) {
// alter holder.a here and it changes.
}
Con valor de retorno
int b = 42;
b = doSomething(b);
public int doSomething(int b) {
return b + 1;
}
técnicamente correcto, pero no terriblemente útil –
Ok, aclararé. –
"Correcto" es una condición booleana, y no admite modificadores de grado o tipo. – tchrist
pasar un objeto que tiene ese valor como un campo.
Una opción es utilizar clases como java.lang.Integer, entonces no está pasando un primitivo en absoluto.
Por otra parte, sólo puede utilizar un código como:
int a = 5;
a = func(a);
y func han devolver el valor modificado.
java.lang.Entero y amigos son inmutables. java.util.concurrent.atomic.AtomicInteger y sus amigos son mutables. Otra opción (algo burda) que he visto es usar una matriz de 1 elemento. –
¡Esta es una forma de lograrlo, por un solo valor! –
No puede. Pero se puede devolver un número entero que es un valor modificado
int i = 0;
i = doSomething(i);
Si está de paso en más de una puede que desee crear una (una clase específicamente para contener un conjunto de variables que se pueden pasar a clases) Data Transfer Object .
Pase un AtomicInteger
, AtomicBoolean
, etc. en su lugar. No hay uno para cada tipo primitivo, pero puede usar, por ejemplo, un AtomicReference<Short>
si es necesario también.
Nota: raramente debería haber una necesidad de hacer algo como esto en Java. Cuando quiera hacerlo, le recomendaría que reconsidere lo que está tratando de hacer y que vea si no puede hacerlo de otra manera (usando un método que devuelva int
, digamos ... qué es exactamente lo mejor para do es variará de una situación a otra).
+1 aunque creo que esto podría ser pesado en comparación con solo usar un objeto envoltorio/titular. –
Si solo usa 'set (int)' para mutarlo, no creo que haya ningún impacto en el rendimiento que valga la pena preocuparse por ... crear su propio contenedor mutable para hacer esto (o importar commons-lang, para el caso ...) sería una ofensa mucho peor en mi opinión. Además, espero que esto no se haga con mucha frecuencia, ya que no creo que haya muchos casos en que esto realmente se necesite. – ColinD
Estoy de acuerdo en importar commons-lang siendo una mala idea. Supongo que OP es un programador de C y quiere seguir usando los mismos paradigmas que conducen a la mayoría de las complejidades para comprender un programa de C, así que imagino que usará esta solución "pasar primitivo por referencia" con bastante frecuencia. . –
Eso no es posible en Java, como alternativa puede envolverlo en una única matriz de elementos.
void demo() {
int [] a = { 0 };
increment (a)
}
void increment(int [] v) {
v[0]++;
}
Pero siempre hay mejores opciones.
- 1. Esquema de paso por referencia
- 2. Entero como tipo primitivo
- 3. Cambiar el valor de un tipo de datos primitivo envuelto
- 4. ¿Es String un tipo primitivo?
- 5. ¿Cómo convertir un tipo definido por el usuario a un tipo primitivo?
- 6. ¿Por qué usar = para inicializar un tipo primitivo en C++?
- 7. Objeto o tipo primitivo
- 8. .NET Paso de parámetros - por referencia v/s por valor
- 9. Tipo de datos escalar vs. primitivo: ¿son lo mismo?
- 10. ¿Por qué no hay ningún tipo primitivo para Cadena?
- 11. ¿Cómo paso un objeto por valor?
- 12. Delphi paso de parámetros por referencia o por valor/copia
- 13. C# Paso tipo de referencia directamente vs parámetro out
- 14. ¿Cómo funciona el paso por referencia realmente en C#?
- 15. ¿Cómo determinar el tipo primitivo de una variable primitiva?
- 16. R: Al pasar un marco de datos por referencia
- 17. ¿Las matrices de Matlab son transferidas paso por valor o paso por referencia?
- 18. ¿Volátil o sincronizado para el tipo primitivo?
- 19. Verifique el tipo de campo primitivo
- 20. shared_ptr - paso por valor vs pase por referencia
- 21. Java: copiar matriz de tipo no primitivo
- 22. paso por el puntero y Pasar por referencia
- 23. universal Analizar Tipo primitivo en C#
- 24. lo que es diferente entre el paso por valor y el paso por referencia usando C#
- 25. Jackson deserializar a lo específico tipo primitivo
- 26. ¿Cómo determinar y verificar si un tipo en el ensamblaje es tipo personalizado o tipo primitivo usando reflexión en .NET?
- 27. ¿Con qué propósito Java tiene un tipo primitivo flotante?
- 28. ¿Cómo paso una referencia constante en C#?
- 29. Encuentra dinámicamente la clase que representa un tipo Java primitivo
- 30. determinar el tipo complejo de un tipo primitivo utilizando la reflexión
Creo que esto también se aplica a 'Integer' –