Sin significado especial. Solo quise decir muy importante. Es decir, java.lang.Stringtener un tratamiento especial del lenguaje Java.
johnchen902
16
¿Quién dice que la cadena es "una clase como cualquier otra"? Es una clase muy especial, diferente a cualquier otra. Dado que su suposición es falsa, la pregunta no es realmente responsable.
Eric Lippert
55
El hecho de que la suposición sea falsa no significa que la pregunta no tenga respuesta. Y la respuesta correcta ya tiene 197 votos.
Los diseñadores de Java decidieron retener los tipos primitivos en un lenguaje orientado a objetos, en lugar de convertir todo en un objeto, para mejorar el rendimiento del lenguaje. Las primitivas se almacenan en la pila de llamadas, que requieren menos espacios de almacenamiento y son más baratas de manipular. Por otro lado, los objetos se almacenan en el montón de programas, que requieren una gestión de memoria compleja y más espacios de almacenamiento.
Por razones de rendimiento, la cadena de Java está diseñada para estar entre una primitiva y una clase.
Nota: Los literales de cadena se almacenan en un grupo común. Esto facilita el intercambio de almacenamiento para cadenas con el mismo contenido para conservar el almacenamiento. Stringlos objetos asignados a través de un nuevo operador se almacenan en el heap, y no se comparte el almacenamiento de los mismos contenidos.
Tenga en cuenta que el "grupo común" suele formar parte del montón.
Joachim Sauer
3
@JoachimSauer Sí ... con pequeños beneficios :) agregó eso en la nota. Gracias por recordar.
Suresh Atta
2
Entonces, ¿es más rápido escribir String s1 = "Hello"; que String s2 = new String ("Hola") ;?
user2097804
28
Agregaría eso en su ejemplo s1 == s2 == s3 pero s4! = S5
Alfredo Osorio
8
@AndrewJanke en el hotspot reciente jvm (7), el grupo de cadenas no está en perm gen y desde Java 8 ya no hay perm gen ...
assylias
50
Java trata a String como una clase especial, puede inicializar en ambos sentidos
Asignando directamente literal
String a ="adsasdf";
Como otros objetos que usan una nueva palabra clave
String a =newString("adsasdf");
Debe tener especial cuidado cuando quiera comparar con el ==signo:
String a ="asdf";String b ="asdf";System.out.println(a == b);// TrueSystem.out.println(a.equals(b));// TrueString a =newString("asdf");String b =newString("asdf");System.out.println(a == b);// FalseSystem.out.println(a.equals(b));// True
Esto se debe a que, en el primer caso, los objetos a y b se mantienen en algo llamado literal pooly ambos hacen referencia al mismo objeto, por lo que son iguales en ambos sentidos.
Pero en el segundo caso, ayb hace referencia a diferentes objetos, como cuando inicializamos cualquier otro objeto. por lo que son desiguales en comparación con el ==operador, mientras que son iguales en valores.
Tampoco sabía que el "tipo nulo" es un tipo apropiado en Java. Su información muy útil, debe aumentar el tamaño de la fuente.
Grijesh Chauhan
1
@GrijeshChauhan: bueno, el "tipo nulo" es una redacción ingeniosa que permite nullasignar cualquiera a cualquier variable de tipo de referencia. No es un tipo interesante, de lo contrario.
Joachim Sauer
15
Es una característica del lenguaje Java. Los literales de cadena en el código fuente reciben un tratamiento especial.
La especificación del lenguaje, aquí , simplemente dice que un literal de cadena es de Stringtipo
Las cadenas se usan muy a menudo en un lenguaje de programación. Como Java está orientado a objetos, una cadena es un objeto. Para evitar la nueva cadena engorrosa ("someString"); cada vez que necesite un objeto de cadena, java le permite crear un objeto de cadena usando el literal de cadena.
Pero debes tener en cuenta la igualdad de cuerdas. Aquí una breve prueba JUnit para demostrar lo que quiero decir.
@Testpublicvoid stringTest(){// a string literal and a string object created // with the same literal are equal
assertEquals("string",newString("string"));// two string literals are the same string object
assertSame("string","string");// a string literal is not the same object instance // as a string object created with the same string literal
assertFalse("string"==newString("string"));// java's String.intern() method gives you the same// string object reference for all strings that are equal.
assertSame("string",newString("string").intern());}
Si solo pudiera inicializar una cadena con new String(String src), entonces ni siquiera podría darle al constructor un literal de cadena. Tendría que inicializar a char [], y luego usar el String(char [] src)constructor para construir la cadena, o tendría que leer la cadena de un archivo.
AJMansfield
Eso no es correcto. Un literal de cadena es solo una secuencia de caracteres en un archivo fuente rodeado de comillas dobles. Java crea automáticamente una instancia de una cadena usando este literal. Por lo tanto, un objeto literal y un objeto String son iguales, pero no son lo mismo. Java también podría haberse implementado de esta manera, por lo que debe usar una nueva Cadena (""); instanciar un objeto String, pero esto solo haría nuestra vida más difícil. Entonces, cuando escribe una nueva cadena ("una cadena"), Java crea un objeto de cadena para el literal "una cadena" y pasa este objeto de cadena al constructor de la nueva cadena.
René Link
2
Solo por mencionar. Un literal de cadena es una referencia a una instancia de clase String, puede escribir código como este:
- String es una clase en Java . Tiene razón al respecto, por lo que siempre podemos inicializar con la newpalabra clave.
- Pero cuando hacemos algo como:
String s = "";
La declaración anterior está marcada por el compilador como un objeto String especial y luego JVM durante la carga de la clase (la carga se realiza antes de la inicialización), ve esto lo que se conoce como un literal de cadena , que se almacena en un grupo de literales de cadena .
- Por lo tanto, se puede crear una Cadena usando new()y por el ""método, pero este último proporciona un literal de cadena que permanece en el montón incluso cuando no hay referencia a ese objeto de cadena, porque tiene una referencia del grupo de literales de cadena.
El proceso que describe no es lo que Java realmente hace: como ya han dicho otros, "hello"es un literal de cadena y el compilador lo colocará en el grupo constante, consulte JLS §3.10.5 y JVMS §5.1 .
siegi
1
Java.lang.StringNo es solo una clase. Es una parte integral del lenguaje central. El compilador tiene azúcar sintáctica para ello. Por ejemplo, ""es como una abreviatura de new String(""). Cuando se escribe, ""el compilador optimiza cadenas idénticas a la misma instancia para ahorrar espacio."a" + 5 == "a5" ==> true
El compilador tiene azúcar sintáctica para muchas cosas, incluyendo no tener que encajonar / desempaquetar entre versiones de objeto y sus tipos nativos, sin padre significa Objeto, constructor predeterminado, ...
""no es una abreviatura de new String(""). Si lo usa "", lo primero que se hará es buscar coincidencias en el conjunto de cadenas de la JVM y, si eso es cierto, devolverá esa cadena. Al usarlo new String(""), siempre creará una nueva Cadena, incluso si la Cadena misma ya existe en el grupo de Cadena (porque no se almacenará en el grupo de Cadena).
g00glen00b
Actualicé mi respuesta. ¿La gente usa esto para su ventaja, como usar constantes de cadena como un equivalente al tipo de símbolo Lisp?
" "
ya es una cadena!java.lang.String
tener un tratamiento especial del lenguaje Java.Respuestas:
Java String es especial
Por ejemplo
Nota: Los literales de cadena se almacenan en un grupo común. Esto facilita el intercambio de almacenamiento para cadenas con el mismo contenido para conservar el almacenamiento.
String
los objetos asignados a través de un nuevo operador se almacenan en elheap
, y no se comparte el almacenamiento de los mismos contenidos.fuente
Java trata a String como una clase especial, puede inicializar en ambos sentidos
Asignando directamente literal
Como otros objetos que usan una nueva palabra clave
Debe tener especial cuidado cuando quiera comparar con el
==
signo:Esto se debe a que, en el primer caso, los objetos a y b se mantienen en algo llamado
literal pool
y ambos hacen referencia al mismo objeto, por lo que son iguales en ambos sentidos.Pero en el segundo caso, ayb hace referencia a diferentes objetos, como cuando inicializamos cualquier otro objeto. por lo que son desiguales en comparación con el
==
operador, mientras que son iguales en valores.fuente
La cadena recibe un tratamiento especial en el JLS: es uno de los dos tipos no primitivos para los que existen literales (el otro es
Class
) * .De la JLS :
* bueno, también existe el "tipo nulo" con su "literal nulo"
null
, pero la mayoría de la gente no piensa en el "tipo nulo" como un tipo apropiado.fuente
null
asignar cualquiera a cualquier variable de tipo de referencia. No es un tipo interesante, de lo contrario.Es una característica del lenguaje Java. Los literales de cadena en el código fuente reciben un tratamiento especial.
La especificación del lenguaje, aquí , simplemente dice que un literal de cadena es de
String
tipofuente
El texto entre comillas dobles crea un
String
objeto literal .El código anterior crea un
String
objeto, usando comillas dobles.fuente
Las cadenas se usan muy a menudo en un lenguaje de programación. Como Java está orientado a objetos, una cadena es un objeto. Para evitar la nueva cadena engorrosa ("someString"); cada vez que necesite un objeto de cadena, java le permite crear un objeto de cadena usando el literal de cadena.
Pero debes tener en cuenta la igualdad de cuerdas. Aquí una breve prueba JUnit para demostrar lo que quiero decir.
fuente
new String(String src)
, entonces ni siquiera podría darle al constructor un literal de cadena. Tendría que inicializar achar []
, y luego usar elString(char [] src)
constructor para construir la cadena, o tendría que leer la cadena de un archivo.Solo por mencionar. Un literal de cadena es una referencia a una instancia de clase String, puede escribir código como este:
fuente
- String es una clase en Java . Tiene razón al respecto, por lo que siempre podemos inicializar con la
new
palabra clave.- Pero cuando hacemos algo como:
String s = "";
La declaración anterior está marcada por el compilador como un objeto String especial y luego JVM durante la carga de la clase (la carga se realiza antes de la inicialización), ve esto lo que se conoce como un literal de cadena , que se almacena en un grupo de literales de cadena .
- Por lo tanto, se puede crear una Cadena usando
new()
y por el""
método, pero este último proporciona un literal de cadena que permanece en el montón incluso cuando no hay referencia a ese objeto de cadena, porque tiene una referencia del grupo de literales de cadena.fuente
Java hace un proceso de dos pasos para nosotros.
es equivalente a
Al igual que [.NET] [1] tiene algo similar.
hace
Agregar referencias: -
fuente
"hello"
es un literal de cadena y el compilador lo colocará en el grupo constante, consulte JLS §3.10.5 y JVMS §5.1 .Java.lang.String
No es solo una clase. Es una parte integral del lenguaje central. El compilador tiene azúcar sintáctica para ello. Por ejemplo,""
es como una abreviatura denew String("")
. Cuando se escribe,""
el compilador optimiza cadenas idénticas a la misma instancia para ahorrar espacio."a" + 5 == "a5" ==> true
El compilador tiene azúcar sintáctica para muchas cosas, incluyendo no tener que encajonar / desempaquetar entre versiones de objeto y sus tipos nativos, sin padre significa Objeto, constructor predeterminado, ...
fuente
""
no es una abreviatura denew String("")
. Si lo usa""
, lo primero que se hará es buscar coincidencias en el conjunto de cadenas de la JVM y, si eso es cierto, devolverá esa cadena. Al usarlonew String("")
, siempre creará una nueva Cadena, incluso si la Cadena misma ya existe en el grupo de Cadena (porque no se almacenará en el grupo de Cadena).