android - How to test the backing array used in Java Sting? -


while developing android application, attention caught backing array.

multiple strings can share same char[] because strings immutable. substring(int) method returns string shares backing array of source string. optimization: fewer character arrays need allocated, , less copying necessary. can lead unwanted heap retention. taking short substring of long string means long shared char[] won't garbage until both strings garbage. typically happens when parsing small substrings out of large input. avoid necessary, call new string(longstring.substring(...)). string copy constructor ensures backing array no larger necessary.

then have read many resources on web. know strings no longer shares same backing array since jdk7u6, pointed mark rotteveel.

then started trying play with, , test existence of shared backing array in code:

string str = "1234567890"; system.out.println("str.substring(1): "    + (str == str.substring(1))); system.out.println("str.substring(0, 9): " + (str == str.substring(0, 9))); 

first assume == swallow equal comparison (isn't it?) compares memory locations (like in c).

if do share same backing array, , == comparing memory locations, both statements should return true (or @ least last 1 returns true).

however, both false.

well, think laptop having java 7 update 21. (shown in win7 -> control panel -> java control panel -> about) (and in eclipse -> window -> preference -> java -> compiler -> compiler compliance level: {1.3 , 1.4 , 1.5 , 1.6 , 1.7} )

and know 1.7 means java 7. , know java 7 high shared backing array may have taken away. why have asked eclipse compile project 1.5 , 1.6.

java project -> properties -> java complier -> compiler compliance level = 1.5 

however, said, still getting false in println()s.

let me summarise questions:

q1) how use java codes verify there use of underlying backing array? (other making outofmemoryerror millions of substring()s)

q1) a. == sallow equal comparison?

q1) b. using java 5/6 compile, if set compiler compliance level = 1.5/1.6?

thanks input :-)

the string objects compare different if share same backing char array, because string objects different objects.

you can backing array using reflection. on system name of backing array value there no guarantee same on yours.

import java.lang.reflect.*;  public class main {     static field stringbackingfield = null;      public static void main(string[] args) throws exception     {         string stra = "1234567890";         string strb = "1234567890";         char[] chara = getbackingarray(stra);         char[] charb = getbackingarray(strb);         char[] suba1 = getbackingarray(stra.substring(1));         char[] suba2 = getbackingarray(stra.substring(0, 9));         system.out.println("chara address: " + system.identityhashcode(chara));         system.out.println("charb address: " + system.identityhashcode(charb));         system.out.println("suba1 address: " + system.identityhashcode(suba1));         system.out.println("suba2 address: " + system.identityhashcode(suba2));         system.out.println("chara == charb: " + (chara == charb));         system.out.println("chara == suba1: " + (chara == suba1));         system.out.println("chara == suba2: " + (chara == suba2));     }      public static char[] getbackingarray(string s) throws exception     {         if (stringbackingfield == null)         {             stringbackingfield = string.class.getdeclaredfield("value");             stringbackingfield.setaccessible(true);         }         return (char[]) stringbackingfield.get(s);     } } 

output on java 6:

$ /usr/lib/jvm/java-6-openjdk-amd64/bin/java -version java version "1.6.0_27" openjdk runtime environment (icedtea6 1.12.3) (6b27-1.12.3-0ubuntu1~12.04.1) openjdk 64-bit server vm (build 20.0-b12, mixed mode) $ /usr/lib/jvm/java-6-openjdk-amd64/bin/java main  chara address: 1383884648 charb address: 1383884648 suba1 address: 1383884648 suba2 address: 1383884648 chara == charb: true chara == suba1: true chara == suba2: true 

output on java 7:

$ /usr/lib/jvm/java-7-openjdk-amd64/bin/java -version java version "1.7.0_15" openjdk runtime environment (icedtea7 2.3.7) (7u15-2.3.7-0ubuntu1~12.04.1) openjdk 64-bit server vm (build 23.7-b01, mixed mode) $ /usr/lib/jvm/java-7-openjdk-amd64/bin/java main chara address: 1264720121 charb address: 1264720121 suba1 address: 357935641 suba2 address: 722623040 chara == charb: true chara == suba1: false chara == suba2: false 

edit:

to find name of backing array member print members using

java.util.arrays.tostring(string.class.getdeclaredfields()); 

and 1 type char[].


Comments

Popular posts from this blog

c# - Send Image in Json : 400 Bad request -

javascript - addthis share facebook and google+ url -

ios - Show keyboard with UITextField in the input accessory view -