Ve včerejším článku zmínil Karel Čížek velmi zajímavou věc, která zůstala v diskuzi pod ním nepovšimnuta. Od některé velmi nedávné verze JDK (v 1.7 u11 už tomu tak je) jsou ze Stringu odstraněny intové fieldy count a offset a zůstává tak pouze char[] value (+ cachovaný hashcode). To má za následek jednak zmenšení stringů o 8 bajtů a jednak přestává platit zmiňované sdílení char polí při použití metody substring():
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); }
Poslední řádka zde volá standardní veřejný konstruktor, který char pole kopíruje. Package-private String(int, int, char[]) byl označen jako deprecated (v JDK 8 je už odstraněn úplně) a metody jako concat, replace atd. byly upraveny tak, že nyní používají nový neveřejný konstruktor, který sice char pole také nekopíruje, nicméně je mu vždy předáváno pole nově vytvořené.
/* * Package private constructor which shares value array for speed. * this constructor is always expected to be called with share==true. * a separate constructor is needed because we already have a public * String(char[]) constructor that makes a copy of the given char[]. */ String(char[] value, boolean share) { // assert share : "unshared not supported"; this.value = value; }