Diferencia entre objeto de cadena y literal de cadena [duplicado]
Cuál es la diferencia entre
String str = new String("abc");
y
String str = "abc";
Cuando usa un literal de cadena, la cadena se puede internar , pero cuando lo usa, new String("...")
obtiene un nuevo objeto de cadena.
En este ejemplo, ambas cadenas literales hacen referencia al mismo objeto:
String a = "abc";
String b = "abc";
System.out.println(a == b); // true
Aquí se crean 2 objetos diferentes y tienen referencias diferentes:
String c = new String("abc");
String d = new String("abc");
System.out.println(c == d); // false
En general, se debe utilizar la notación literal de cadena cuando sea posible. Es más fácil de leer y le da al compilador la oportunidad de optimizar su código.
Un literal de cadena es un concepto del lenguaje Java. Este es un literal de cadena:
"a String literal"
Un objeto String es una instancia individual de la java.lang.String
clase.
String s1 = "abcde";
String s2 = new String("abcde");
String s3 = "abcde";
Todos son válidos, pero tienen una ligera diferencia. s1
se referirá a un objeto String interno . Esto significa que la secuencia de caracteres "abcde"
se almacenará en un lugar central y cada vez que "abcde"
se vuelva a utilizar el mismo literal, la JVM no creará un nuevo objeto String sino que utilizará la referencia de la String almacenada en caché .
s2
Se garantiza que será un nuevo objeto String , por lo que en este caso tenemos:
s1 == s2 // is false
s1 == s3 // is true
s1.equals(s2) // is true
La respuesta larga está disponible aquí , así que te daré la corta.
Cuando haces esto:
String str = "abc";
Estás llamando al intern()
método en String . Este método hace referencia a un grupo interno de String
objetos. Si la cadena que invocó ya reside en el grupo, entonces se asigna intern()
una referencia a . De lo contrario, el nuevo se coloca en el grupo y luego se le asigna una referencia a .String
str
String
str
Dado el siguiente código:
String str = "abc";
String str2 = "abc";
boolean identity = str == str2;
Cuando verificas la identidad del objeto haciendo ==
(literalmente estás preguntando: ¿estas dos referencias apuntan al mismo objeto?), obtienes true
.
Sin embargo, no es necesariointern()
Strings
. Puedes forzar la creación de algo nuevo Object
en el montón haciendo esto:
String str = new String("abc");
String str2 = new String("abc");
boolean identity = str == str2;
En este caso, str
y str2
son referencias a diferentes Objects
, ninguno de los cuales ha sido internado , de modo que cuando pruebes Object
la identidad usando ==
, obtendrás false
.
En términos de buenas prácticas de codificación: no lo utilice ==
para comprobar la igualdad de cadenas, utilícelo .equals()
en su lugar.
Como las cadenas son inmutables, cuando lo haces:
String a = "xyz"
Mientras crea la cadena, la JVM busca en el grupo de cadenas si ya existe un valor de cadena "xyz"
; de ser así, 'a'
simplemente será una referencia de esa cadena y no se crea ningún nuevo objeto String.
Pero si dices:
String a = new String("xyz")
obliga a JVM a crear una nueva String
referencia, incluso si "xyz"
está en su grupo.
Para más información lea esto .