class StringTesting { public static void main(String args[]) { String str = "abcd"; String str1 = new String("abcd"); String str2 = str.substring(0,2); String str3 = str.substring(0,2); String str4 = str.substring(0,str.length()); String str5 = str1.substring(0,2); String str6 = str1.substring(0,2); String str7 = str1.substring(0,str1.length()); System.out.println(str2 == str3); System.out.println(str == str4); System.out.println(str5 == str6); System.out.println(str1 == str7); } }
Aquí está la salida que obtengo en java 1.6.0_27:
false true false true
¿Alguien puede explicar la salida? Sé que Java diferencia entre String almacenado en heap y String almacenado en String “common pool” (que puede ser internado). Internamente, ¿cómo es su representación diferente? ¿Cómo cambia el algoritmo de la subcadena? Favor de citar el libro / artículo / blogs, etc. cuando corresponda.
Ver los comentarios:
String str = "abcd"; // new String LITERAL which is interned in the pool String str1 = new String("abcd"); // new String, not interned: str1 != str String str2 = str.substring(0,2); // new String which is a view on str String str3 = str.substring(0,2); // same: str3 != str2 String str7 = str1.substring(0,str1.length()); // special case: str1 is returned
Notas:
Caso especial cuando llamas a str1.substring(0,str1.length());
– ver código:
public String substring(int beginIndex, int endIndex) { //some exception checking then return ((beginIndex == 0) && (endIndex == value.length)) ? this : new String(value, beginIndex, subLen); }
EDITAR
¿Qué es una vista?
Hasta Java 7u6, una Cadena es básicamente una char[]
que contiene los caracteres de la cuerda con un desplazamiento y un conteo (es decir, la cuerda se compone de caracteres de count
comenzando desde la posición de offset
en el char[]
).
Cuando se llama a subcadena, se crea una nueva cadena con el mismo char[]
pero un desplazamiento / conteo diferente, para crear efectivamente una vista en la cadena original. (Excepto cuando count = length y offset = 0 como se explicó anteriormente).
Desde java 7u6, se crea un nuevo char[]
cada vez, porque no hay más campos de count
o offset
en la clase de cadena.
¿Dónde se almacena exactamente el conjunto común?
Esto es específico de la implementación. La ubicación de la agrupación se ha movido en versiones recientes. En versiones más recientes, se almacena en el montón.
¿Cómo se maneja el grupo?
Características principales:
new String("abc").intern();
) S
(porque es un literal o porque se llama intern()
), la JVM devolverá una referencia a una cadena en la agrupación si hay una que sea equals
a S
(de ahí "abc" == "abc"
siempre debe volverse verdadero). String
es un objeto inmutable.
String#subString
– crea una nueva String. Fuente
En código es [abrir jdk 6] –
public String substring(int beginIndex, int endIndex) { if (beginIndex < 0) { throw new StringIndexOutOfBoundsException(beginIndex); } if (endIndex > value.length) { throw new StringIndexOutOfBoundsException(endIndex); } int subLen = endIndex - beginIndex; if (subLen < 0) { throw new StringIndexOutOfBoundsException(subLen); } return ((beginIndex == 0) && (endIndex == value.length)) ? this : new String(value, beginIndex, subLen); }