Estoy acostumbrado a hacer lo siguiente en C
:
void main() {
String zText = "";
fillString(zText);
printf(zText);
}
void fillString(String zText) {
zText += "foo";
}
Y la salida es:
foo
Sin embargo, en Java, esto no parece funcionar. Supongo que porque el String
objeto se copia en lugar de pasar por referenciado . Pensé que las cadenas eran objetos, que siempre se pasan por referencia.
¿Que esta pasando aqui?
java
string
pass-by-reference
Soren Johnson
fuente
fuente
Respuestas:
Tienes tres opciones:
Use un StringBuilder:
Cree una clase de contenedor y pase una instancia del contenedor a su método:
Crea una matriz:
Desde el punto de vista del rendimiento, StringBuilder suele ser la mejor opción.
fuente
StringBuilder
es más rápidos += "..."
ya que no asigna nuevos objetos String cada vez. De hecho, cuando escribe código Java comos = "Hello " + name
, entonces el compilador generará un código de bytes que crea ayStringBuilder
llamaappend()
dos veces.En Java no se pasa nada por referencia . Todo pasa por valor . Las referencias a objetos se pasan por valor. Además, las cadenas son inmutables . Entonces, cuando anexas la cadena aprobada, obtienes una nueva cadena. Puede usar un valor de retorno o pasar un StringBuffer en su lugar.
fuente
Lo que sucede es que la referencia se pasa por valor, es decir, se pasa una copia de la referencia. No se pasa nada en Java por referencia, y dado que una cadena es inmutable, esa asignación crea un nuevo objeto de cadena al que ahora apunta la copia de la referencia . La referencia original todavía apunta a la cadena vacía.
Esto sería lo mismo para cualquier objeto, es decir, establecerlo en un nuevo valor en un método. El siguiente ejemplo solo hace que lo que está sucediendo sea más obvio, pero concatenar una cadena es realmente lo mismo.
fuente
java.lang.String es inmutable.
Odio pegar las URL, pero https://docs.oracle.com/javase/10/docs/api/java/lang/String.html es esencial para que puedas leer y comprender si estás en Java.
fuente
los objetos se pasan por referencia, las primitivas se pasan por valor.
La cadena no es una primitiva, es un objeto y es un caso especial de objeto.
Esto es para ahorrar memoria. En JVM, hay un grupo de cadenas. Para cada cadena creada, JVM intentará ver si existe la misma cadena en el grupo de cadenas y la señalará si ya existiera.
/ * SALIDA * /
el == está verificando la dirección de memoria (referencia), y el .equals está verificando el contenido (valor)
fuente
Todos los argumentos en Java se pasan por valor. Cuando pasa un
String
a una función, el valor que se pasa es una referencia a un objeto String, pero no puede modificar esa referencia, y el objeto String subyacente es inmutable.La asignación
es equivalente a:
Es decir, (localmente) reasigna el parámetro
zText
como una nueva referencia, que apunta a una nueva ubicación de memoria, en la que hay una nuevaString
que contiene el contenido original dezText
con"foo"
agregado.El objeto original no se modifica y la
main()
variable local del métodozText
todavía apunta a la cadena original (vacía).huellas dactilares:
Si desea modificar la cadena, puede, como se ha señalado, utilizar
StringBuilder
un contenedor (una matriz o unaAtomicReference
clase de contenedor personalizada) que le brinde un nivel adicional de indirección de puntero. Alternativamente, solo devuelva el nuevo valor y asígnelo:huellas dactilares:
Esta es probablemente la solución más similar a Java en el caso general: consulte el elemento de Java efectivo "Favorecer la inmutabilidad".
Sin embargo, como se señaló anteriormente,
StringBuilder
a menudo le brindará un mejor rendimiento, si tiene que agregar mucho, particularmente dentro de un ciclo, useStringBuilder
.Pero intente pasar inmutable en
Strings
lugar de mutableStringBuilders
si puede: su código será más fácil de leer y más fácil de mantener. Considere hacer sus parámetrosfinal
y configurar su IDE para que le avise cuando reasigne un parámetro de método a un nuevo valor.fuente
La cadena es un objeto inmutable en Java. Puede usar la clase StringBuilder para hacer el trabajo que está tratando de lograr, de la siguiente manera:
Otra opción es crear una clase con una Cadena como variable de alcance (altamente desaconsejada) de la siguiente manera:
fuente
La respuesta es simple. En java las cuerdas son inmutables. Por lo tanto, es como usar el modificador 'final' (o 'const' en C / C ++). Entonces, una vez asignado, no puede cambiarlo como lo hizo.
Puede cambiar el valor al que apunta una cadena, pero NO puede cambiar el valor real al que apunta actualmente esta cadena.
Es decir.
String s1 = "hey"
. Puede hacers1 = "woah"
, y eso está totalmente bien, pero en realidad no puede cambiar el valor subyacente de la cadena (en este caso: "hey") para que sea algo diferente una vez que se asigna usando plusEquals, etc. (es decirs1 += " whatup != "hey whatup"
).Para hacer eso, use las clases StringBuilder o StringBuffer u otros contenedores mutables, luego simplemente llame a .toString () para convertir el objeto nuevamente en una cadena.
nota: las cadenas a menudo se usan como claves hash, por lo tanto, esa es una de las razones por las que son inmutables.
fuente
=
en una referencia NUNCA afecta el objeto al que solía señalar, independientemente de la clase.String es una clase especial en Java. Es seguro para subprocesos, lo que significa "Una vez que se crea una instancia de String, el contenido de la instancia de String nunca cambiará".
Esto es lo que está pasando por
Primero, el compilador Java obtendrá el valor de la instancia de zText String, luego creará una nueva instancia de String cuyo valor sea zText agregando "foo". Entonces sabe por qué la instancia a la que apunta zText no cambia. Es totalmente una nueva instancia. De hecho, incluso String "foo" es una nueva instancia de String. Entonces, para esta declaración, Java creará dos instancias de String, una es "foo", otra es el valor de zText add "foo". La regla es simple: el valor de la instancia de String nunca cambiará.
Para el método fillString, puede usar un StringBuffer como parámetro, o puede cambiarlo así:
fuente
Las cadenas son inmutables en Java.
fuente
Esto funciona utiliza StringBuffer
Incluso mejor usar StringBuilder
fuente
La cadena es inmutable en Java. no puede modificar / cambiar, una cadena literal / objeto existente.
Cadena s = "Hola"; s = s + "hola";
Aquí la referencia anterior s se reemplaza por la nueva referencia que apunta al valor "HelloHi".
Sin embargo, para traer mutabilidad tenemos StringBuilder y StringBuffer.
StringBuilder s = new StringBuilder (); s.append ("Hola");
esto agrega el nuevo valor "Hola" a la misma referencia s. //
fuente
Aaron Digulla tiene la mejor respuesta hasta ahora. Una variación de su segunda opción es usar el contenedor o la clase de contenedor MutableObject de la biblioteca commons lang versión 3+:
Guarda la declaración de la clase contenedor. El inconveniente es una dependencia de commons lang lib. Pero la lib tiene una gran cantidad de funciones útiles y casi cualquier proyecto más grande en el que he trabajado la usó.
fuente
Para pasar un objeto (incluyendo String) por referencia en java, puede pasarlo como miembro de un adaptador circundante. Una solución con un genérico está aquí:
fuente
Para alguien que es más curioso.
fuente