retornan - retornar dos valores en java
Las cadenas son objetos en Java, entonces, ¿por qué no usamos ''nuevo'' para crearlos? (13)
Normalmente creamos objetos usando la palabra clave new
, como:
Object obj = new Object();
Las cadenas son objetos, pero no usamos los new
para crearlos:
String str = "Hello World";
¿Por qué es esto? ¿Puedo hacer una cadena con new
?
Además de lo que ya se dijo, los literales de cadena [es decir, las cadenas como "abcd"
pero no como la new String("abcd")
] en Java están intercaladas, esto significa que cada vez que se refiera a "abcd", obtendrá una referencia a una sola instancia de String
, en lugar de una nueva cada vez. Entonces tendrás:
String a = "abcd";
String b = "abcd";
a == b; //True
pero si tuviste
String a = new String("abcd");
String b = new String("abcd");
entonces es posible tener
a == b; // False
(y en caso de que alguien necesite recordatorios, siempre use .equals()
para comparar cadenas; ==
pruebas para la igualdad física).
Los literales de Interning String son buenos porque a menudo se usan más de una vez. Por ejemplo, considere el código (artificial):
for (int i = 0; i < 10; i++) {
System.out.println("Next iteration");
}
Si no tuviéramos el interinato de Strings, "Next iteration" necesitaría ser instanciado 10 veces, mientras que ahora solo se creará una instancia una vez.
Azúcar sintáctica. los
String s = new String("ABC");
la sintaxis aún está disponible.
Casi no es necesario volver a crear una cadena ya que el literal (los caracteres entre comillas) ya es un objeto String creado cuando se carga la clase de host. Es perfectamente legal invocar métodos en un literal y don, la distinción principal es la conveniencia proporcionada por los literales. Sería un gran dolor y una pérdida de tiempo si tuviéramos que crear una serie de caracteres y rellenarlos por char y ellos haciendo una nueva cadena (matriz de caracteres).
El grupo literal contiene cadenas que se crearon sin utilizar la palabra clave new
.
Existe una diferencia: la cadena sin referencia nueva se almacena en el grupo de cadenas String y String con la nueva dice que están en la memoria del montón.
La cadena con nuevo está en otro lugar en la memoria como cualquier otro objeto.
En Java, las cadenas son un caso especial, con muchas reglas que se aplican solo a cadenas. Las comillas dobles hacen que el compilador cree un objeto String. Dado que los objetos String son inmutables, esto permite que el compilador interne múltiples cadenas y construya un grupo de cadenas más grande. Dos constantes de cadena idénticas siempre tendrán la misma referencia de objeto. Si no desea que sea el caso, puede usar una cadena nueva ("") y creará un objeto String en el tiempo de ejecución. El método interno () solía ser común, para hacer que las cadenas creadas dinámicamente se verifiquen con la tabla de búsqueda de cadenas. Una vez que una cadena está interna, la referencia del objeto apuntará a la instancia de cadena canónica.
String a = "foo";
String b = "foo";
System.out.println(a == b); // true
String c = new String(a);
System.out.println(a == c); // false
c = c.intern();
System.out.println(a == c); // true
Cuando el cargador de clases carga una clase, todas las constantes de cadena se agregan al grupo de cadenas.
Es un atajo. Originalmente no era así, pero Java lo cambió.
Esta FAQ habla de esto brevemente. La guía de especificaciones de Java también lo menciona. Pero no puedo encontrarlo en línea.
Las cadenas son objetos "especiales" en Java. Los diseñadores de Java sabiamente decidieron que las cadenas se utilizan tan a menudo que necesitaban su propia sintaxis y una estrategia de almacenamiento en caché. Cuando declaras una cadena diciendo:
String myString = "something";
myString es una referencia al objeto String con un valor de "algo". Si luego declaras:
String myOtherString = "something";
Java es lo suficientemente inteligente como para saber que myString y myOtherString son los mismos y los almacenará en una tabla de cadenas global como el mismo objeto. Se basa en el hecho de que no puede modificar cadenas para hacer esto. Esto reduce la cantidad de memoria requerida y puede hacer comparaciones más rápido.
Si, en cambio, escribes
String myOtherString = new String("something");
Java creará un nuevo objeto para usted, distinto del objeto myString.
Porque String es una clase inmutable en Java.
Ahora, ¿por qué es inmutable? Como String es inmutable, se puede compartir entre varios subprocesos y no es necesario sincronizar el funcionamiento de String externamente. Como String también se usa en el mecanismo de carga de clase. Entonces, si String era mutable, entonces java.io.writer podría haberse cambiado a abc.xyz.mywriter
Siéntete libre de crear una nueva Cadena con
String s = new String("I''m a new String");
La notación usual s = "new String";
es más o menos un atajo conveniente, que debe usarse por motivos de rendimiento, excepto en aquellos casos muy raros, donde realmente se necesitan cadenas que califiquen para la ecuación
(string1.equals(string2)) && !(string1 == string2)
EDITAR
En respuesta al comentario: esto no fue un consejo, sino solo una respuesta directa a la tesis de los cuestionarios, que no usamos la palabra clave ''nueva'' para Strings, lo que simplemente no es cierto. Espero que esta edición (incluida la anterior) aclare esto un poco. Por cierto, hay un par de respuestas buenas y mucho mejores a la pregunta anterior sobre SO.
String está sujeto a un par de optimizaciones (a falta de una frase mejor). Tenga en cuenta que String también tiene sobrecarga del operador (para el operador +), a diferencia de otros objetos. Entonces es un caso especial.
Todavía puede usar una new String("string")
, pero sería más difícil crear cadenas nuevas sin cadenas literales ... tendría que usar matrices de caracteres o bytes :-) Los literales de cadenas tienen una propiedad adicional: todos los mismos literales de cadenas desde cualquier punto de clase a la misma instancia de cadena (están internados).
String a = "abc"; // 1 Object: "abc" added to pool
String b = "abc"; // 0 Object: because it is already in the pool
String c = new String("abc"); // 1 Object
String d = new String("def"); // 1 Object + "def" is added to the Pool
String e = d.intern(); // (e==d) is "false" because e refers to the String in pool
String f = e.intern(); // (f==e) is "true"
//Total Objects: 4 ("abc", c, d, "def").
Espero que esto aclare algunas dudas. :)
TString obj1 = new TString("Jan Peter");
TString obj2 = new TString("Jan Peter");
if (obj1.Name == obj2.Name)
System.out.println("True");
else
System.out.println("False");
Salida:
Cierto
Creé dos objetos separados, ambos tienen un campo (ref) ''Nombre''. Entonces, incluso en este caso, "Jan Peter" se comparte, si entiendo la forma en que trata Java ...