que metodos funciones example java string string-literals

java - metodos - Diferencia entre el objeto de cadena y el literal de cadena



string java que es (13)

Además de las respuestas ya publicadas, también vea this excelente artículo sobre javaranch.

Esta pregunta ya tiene una respuesta aquí:

Cuál es la diferencia entre

String str = new String("abc");

y

String str = "abc";


Como las cuerdas son inmutables, cuando haces:

String a = "xyz"

al crear la cadena, la JVM busca en el conjunto de cadenas si ya existe un valor de cadena "xyz" , si es así, ''a'' simplemente será una referencia de esa cadena y no se creará ningún nuevo objeto String.

Pero si dices:

String a = new String("xyz")

obliga a JVM a crear una nueva referencia de String , incluso si "xyz" está en su grupo.

Para más información lea this .


Cuando usas una cadena literal, la cadena puede ser interned , pero cuando usas una new String("...") obtienes un nuevo objeto de cadena.

En este ejemplo, ambos literales de cadena 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 diferentes referencias:

String c = new String("abc"); String d = new String("abc"); System.out.println(c == d); // false

En general, 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.


En el primer caso, hay dos objetos creados.

En el segundo caso, es solo uno.

Aunque ambas formas, str se refiere a "abc" .


Hay diferencias sutiles entre el objeto String y la cadena literal.

String s = "abc"; // creates one String object and one reference variable

En este caso simple, " abc " entrará en el grupo y s se referirá a él.

String s = new String("abc"); // creates two objects,and one reference variable

En este caso, debido a que usamos la new palabra clave, Java creará un nuevo objeto String en la memoria normal (sin agrupación), y s se referirá a él. Además, el literal " abc " se colocará en el grupo.


La respuesta larga está disponible interned , así que te daré la breve.

Cuando haces esto:

String str = "abc";

Estás llamando al método intern() en String . Este método hace referencia a un grupo interno de objetos String . Si la cadena a la que llamó intern() ya reside en el grupo, se asigna una referencia a esa String a str . Si no, la nueva String se coloca en el grupo, y una referencia a ella se asigna a la str .

Dado el siguiente código:

String str = "abc"; String str2 = "abc"; boolean identity = str == str2;

Cuando verifica la identidad del objeto haciendo == (literalmente está preguntando: ¿estas dos referencias apuntan al mismo objeto?), Se vuelve true .

Sin embargo, no es necesario que intern() Strings . Puede forzar la creación de un 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 prueba la identidad del Object utilizando == , obtendrá false .

En términos de buenas prácticas de codificación: no use == para verificar la igualdad de cadenas, use .equals() lugar.


Las siguientes son algunas comparaciones:

String s1 = "Hello"; String s2 = "Hello"; String s3 = new String("Hello"); System.out.println(s1 == s2); //true System.out.println(s1.equals(s2)); //true System.out.println(s1 == s3); //false System.out.println(s1.equals(s3)); //true s3 = s3.intern(); System.out.println(s1 == s3); //true System.out.println(s1.equals(s3)); //true

Cuando se llama intern() se cambia la referencia.


Según String son equivalentes.

La documentación para String(String original) también dice que: A menos que se necesite una copia explícita del original, el uso de este constructor no es necesario ya que las Strings son inmutables.

Busque otras respuestas, porque parece que la documentación de Java es engañosa :(


String es una clase en Java diferente de otros lenguajes de programación. Así que para cada clase la declaración de objeto y la inicialización es

String st1 = new String();

o

String st2 = new String("Hello"); String st3 = new String("Hello");

Aquí, st2 , st2 y st3 son objetos diferentes.

Es decir:

st1 == st2 // false st1 == st3 // false st2 == st3 // false

Debido a que st2 , st2 , st3 hacen referencia a 3 objetos diferentes, y == comprueba la igualdad en la ubicación de la memoria, de ahí el resultado.

Pero:

st1.equals(st2) // false st2.equals(st3) // true

Aquí el método .equals() verifica el contenido y el contenido de st1 = "" , st2 = "hello" y st3 = "hello" . De ahí el resultado.

Y en el caso de la declaración de cuerdas.

String st = "hello";

Aquí, se llama al método intern() de String clase String , y comprueba si "hello" está en el grupo interno, y si no, se agrega al grupo interno, y si "hello" existe en el grupo interno, st apunta a la Memoria del "hello" existente.

Así que en caso de:

String st3 = "hello"; String st4 = "hello";

Aquí:

st3 == st4 // true

Porque st3 y st4 apuntan a la misma dirección de memoria.

También:

st3.equals(st4); // true as usual


Un literal de cadena es un concepto de lenguaje Java. Este es un literal de cadena:

"a String literal"

Un objeto String es una instancia individual de la clase java.lang.String .

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 internado . Esto significa que la secuencia de caracteres "abcde" se almacenará en un lugar central, y cada vez que se use el mismo literal "abcde" , la JVM no creará un nuevo objeto String, sino que usará la referencia de la String cacheada .

Se garantiza que s2 es un nuevo objeto String , por lo que en este caso tenemos:

s1 == s2 // is false s1 == s3 // is true s1.equals(s2) // is true


Un poco de desmontaje siempre es interesante ...

$ cat Test.java public class Test { public static void main(String... args) { String abc = "abc"; String def = new String("def"); } } $ javap -c -v Test Compiled from "Test.java" public class Test extends java.lang.Object SourceFile: "Test.java" minor version: 0 major version: 50 Constant pool: const #1 = Method #7.#16; // java/lang/Object."<init>":()V const #2 = String #17; // abc const #3 = class #18; // java/lang/String const #4 = String #19; // def const #5 = Method #3.#20; // java/lang/String."<init>":(Ljava/lang/String;)V const #6 = class #21; // Test const #7 = class #22; // java/lang/Object const #8 = Asciz <init>; ... { public Test(); ... public static void main(java.lang.String[]); Code: Stack=3, Locals=3, Args_size=1 0: ldc #2; // Load string constant "abc" 2: astore_1 // Store top of stack onto local variable 1 3: new #3; // class java/lang/String 6: dup // duplicate top of stack 7: ldc #4; // Load string constant "def" 9: invokespecial #5; // Invoke constructor 12: astore_2 // Store top of stack onto local variable 2 13: return }


"abc" es una cadena literal.

En Java, estas cadenas literales se agrupan internamente y se utiliza la misma instancia de Cadena de "abc" siempre que tenga esa cadena literal declarada en su código. Entonces "abc" == "abc" siempre será verdadero ya que ambos son la misma instancia de String.

Usando el método String.intern() puede agregar cualquier cadena que desee a las cadenas agrupadas internamente, se mantendrán en la memoria hasta que salga Java.

Por otro lado, el uso de la new String("abc") creará un nuevo objeto de cadena en la memoria, que lógicamente es lo mismo que el literal "abc" . "abc" == new String("abc") siempre será falso, ya que, aunque son lógicamente iguales, se refieren a diferentes instancias.

Envolver un constructor de String alrededor de un literal de cadena no tiene ningún valor, simplemente usa innecesariamente más memoria de la que necesita.


String s = new String("FFFF") crea 2 objetos: "FFFF" string y String object, que apuntan a la cadena "FFFF" , por lo que es como un puntero a puntero (referencia a referencia, no estoy interesado en terminología).

Se dice que nunca debe usar una new String("FFFF")