< prev index next >

src/java.base/share/classes/java/lang/String.java

Print this page

        

*** 27,36 **** --- 27,37 ---- import java.io.ObjectStreamField; import java.io.UnsupportedEncodingException; import java.lang.annotation.Native; import java.lang.invoke.MethodHandles; + import java.lang.compiler.IntrinsicCandidate; import java.lang.constant.Constable; import java.lang.constant.ConstantDesc; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays;
*** 73,83 **** * Here are some more examples of how strings can be used: * <blockquote><pre> * System.out.println("abc"); * String cde = "cde"; * System.out.println("abc" + cde); ! * String c = "abc".substring(2, 3); * String d = cde.substring(1, 2); * </pre></blockquote> * <p> * The class {@code String} includes methods for examining * individual characters of the sequence, for comparing strings, for --- 74,84 ---- * Here are some more examples of how strings can be used: * <blockquote><pre> * System.out.println("abc"); * String cde = "cde"; * System.out.println("abc" + cde); ! * String c = "abc".substring(2,3); * String d = cde.substring(1, 2); * </pre></blockquote> * <p> * The class {@code String} includes methods for examining * individual characters of the sequence, for comparing strings, for
*** 1018,1029 **** if (this == anObject) { return true; } if (anObject instanceof String) { String aString = (String)anObject; ! if (!COMPACT_STRINGS || this.coder == aString.coder) { ! return StringLatin1.equals(value, aString.value); } } return false; } --- 1019,1031 ---- if (this == anObject) { return true; } if (anObject instanceof String) { String aString = (String)anObject; ! if (coder() == aString.coder()) { ! return isLatin1() ? StringLatin1.equals(value, aString.value) ! : StringUTF16.equals(value, aString.value); } } return false; }
*** 1054,1073 **** if (len != sb.length()) { return false; } byte v1[] = value; byte v2[] = sb.getValue(); ! byte coder = coder(); ! if (coder == sb.getCoder()) { int n = v1.length; for (int i = 0; i < n; i++) { if (v1[i] != v2[i]) { return false; } } } else { ! if (coder != LATIN1) { // utf16 str and latin1 abs can never be "equal" return false; } return StringUTF16.contentEquals(v1, v2, len); } return true; --- 1056,1074 ---- if (len != sb.length()) { return false; } byte v1[] = value; byte v2[] = sb.getValue(); ! if (coder() == sb.getCoder()) { int n = v1.length; for (int i = 0; i < n; i++) { if (v1[i] != v2[i]) { return false; } } } else { ! if (!isLatin1()) { // utf16 str and latin1 abs can never be "equal" return false; } return StringUTF16.contentEquals(v1, v2, len); } return true;
*** 1207,1223 **** * lexicographically greater than the string argument. */ public int compareTo(String anotherString) { byte v1[] = value; byte v2[] = anotherString.value; ! byte coder = coder(); ! if (coder == anotherString.coder()) { ! return coder == LATIN1 ? StringLatin1.compareTo(v1, v2) ! : StringUTF16.compareTo(v1, v2); } ! return coder == LATIN1 ? StringLatin1.compareToUTF16(v1, v2) ! : StringUTF16.compareToLatin1(v1, v2); } /** * A Comparator that orders {@code String} objects as by * {@code compareToIgnoreCase}. This comparator is serializable. --- 1208,1223 ---- * lexicographically greater than the string argument. */ public int compareTo(String anotherString) { byte v1[] = value; byte v2[] = anotherString.value; ! if (coder() == anotherString.coder()) { ! return isLatin1() ? StringLatin1.compareTo(v1, v2) ! : StringUTF16.compareTo(v1, v2); } ! return isLatin1() ? StringLatin1.compareToUTF16(v1, v2) ! : StringUTF16.compareToLatin1(v1, v2); } /** * A Comparator that orders {@code String} objects as by * {@code compareToIgnoreCase}. This comparator is serializable.
*** 1237,1253 **** private static final long serialVersionUID = 8575799808933029326L; public int compare(String s1, String s2) { byte v1[] = s1.value; byte v2[] = s2.value; ! byte coder = s1.coder(); ! if (coder == s2.coder()) { ! return coder == LATIN1 ? StringLatin1.compareToCI(v1, v2) ! : StringUTF16.compareToCI(v1, v2); } ! return coder == LATIN1 ? StringLatin1.compareToCI_UTF16(v1, v2) ! : StringUTF16.compareToCI_Latin1(v1, v2); } /** Replaces the de-serialized object. */ private Object readResolve() { return CASE_INSENSITIVE_ORDER; } } --- 1237,1252 ---- private static final long serialVersionUID = 8575799808933029326L; public int compare(String s1, String s2) { byte v1[] = s1.value; byte v2[] = s2.value; ! if (s1.coder() == s2.coder()) { ! return s1.isLatin1() ? StringLatin1.compareToCI(v1, v2) ! : StringUTF16.compareToCI(v1, v2); } ! return s1.isLatin1() ? StringLatin1.compareToCI_UTF16(v1, v2) ! : StringUTF16.compareToCI_Latin1(v1, v2); } /** Replaces the de-serialized object. */ private Object readResolve() { return CASE_INSENSITIVE_ORDER; } }
*** 1317,1328 **** if ((ooffset < 0) || (toffset < 0) || (toffset > (long)length() - len) || (ooffset > (long)other.length() - len)) { return false; } ! byte coder = coder(); ! if (coder == other.coder()) { if (!isLatin1() && (len > 0)) { toffset = toffset << 1; ooffset = ooffset << 1; len = len << 1; } --- 1316,1326 ---- if ((ooffset < 0) || (toffset < 0) || (toffset > (long)length() - len) || (ooffset > (long)other.length() - len)) { return false; } ! if (coder() == other.coder()) { if (!isLatin1() && (len > 0)) { toffset = toffset << 1; ooffset = ooffset << 1; len = len << 1; }
*** 1330,1340 **** if (tv[toffset++] != ov[ooffset++]) { return false; } } } else { ! if (coder == LATIN1) { while (len-- > 0) { if (StringLatin1.getChar(tv, toffset++) != StringUTF16.getChar(ov, ooffset++)) { return false; } --- 1328,1338 ---- if (tv[toffset++] != ov[ooffset++]) { return false; } } } else { ! if (coder() == LATIN1) { while (len-- > 0) { if (StringLatin1.getChar(tv, toffset++) != StringUTF16.getChar(ov, ooffset++)) { return false; }
*** 1412,1428 **** || (ooffset > (long)other.length() - len)) { return false; } byte tv[] = value; byte ov[] = other.value; ! byte coder = coder(); ! if (coder == other.coder()) { ! return coder == LATIN1 ? StringLatin1.regionMatchesCI(tv, toffset, ov, ooffset, len) : StringUTF16.regionMatchesCI(tv, toffset, ov, ooffset, len); } ! return coder == LATIN1 ? StringLatin1.regionMatchesCI_UTF16(tv, toffset, ov, ooffset, len) : StringUTF16.regionMatchesCI_Latin1(tv, toffset, ov, ooffset, len); } /** --- 1410,1425 ---- || (ooffset > (long)other.length() - len)) { return false; } byte tv[] = value; byte ov[] = other.value; ! if (coder() == other.coder()) { ! return isLatin1() ? StringLatin1.regionMatchesCI(tv, toffset, ov, ooffset, len) : StringUTF16.regionMatchesCI(tv, toffset, ov, ooffset, len); } ! return isLatin1() ? StringLatin1.regionMatchesCI_UTF16(tv, toffset, ov, ooffset, len) : StringUTF16.regionMatchesCI_Latin1(tv, toffset, ov, ooffset, len); } /**
*** 1449,1468 **** } byte ta[] = value; byte pa[] = prefix.value; int po = 0; int pc = pa.length; ! byte coder = coder(); ! if (coder == prefix.coder()) { ! int to = (coder == LATIN1) ? toffset : toffset << 1; while (po < pc) { if (ta[to++] != pa[po++]) { return false; } } } else { ! if (coder == LATIN1) { // && pcoder == UTF16 return false; } // coder == UTF16 && pcoder == LATIN1) while (po < pc) { if (StringUTF16.getChar(ta, toffset++) != (pa[po++] & 0xff)) { --- 1446,1464 ---- } byte ta[] = value; byte pa[] = prefix.value; int po = 0; int pc = pa.length; ! if (coder() == prefix.coder()) { ! int to = isLatin1() ? toffset : toffset << 1; while (po < pc) { if (ta[to++] != pa[po++]) { return false; } } } else { ! if (isLatin1()) { // && pcoder == UTF16 return false; } // coder == UTF16 && pcoder == LATIN1) while (po < pc) { if (StringUTF16.getChar(ta, toffset++) != (pa[po++] & 0xff)) {
*** 1691,1706 **** * @param str the substring to search for. * @return the index of the first occurrence of the specified substring, * or {@code -1} if there is no such occurrence. */ public int indexOf(String str) { ! byte coder = coder(); ! if (coder == str.coder()) { return isLatin1() ? StringLatin1.indexOf(value, str.value) : StringUTF16.indexOf(value, str.value); } ! if (coder == LATIN1) { // str.coder == UTF16 return -1; } return StringUTF16.indexOfLatin1(value, str.value); } --- 1687,1701 ---- * @param str the substring to search for. * @return the index of the first occurrence of the specified substring, * or {@code -1} if there is no such occurrence. */ public int indexOf(String str) { ! if (coder() == str.coder()) { return isLatin1() ? StringLatin1.indexOf(value, str.value) : StringUTF16.indexOf(value, str.value); } ! if (coder() == LATIN1) { // str.coder == UTF16 return -1; } return StringUTF16.indexOfLatin1(value, str.value); }
*** 2158,2209 **** * @param replacement The replacement sequence of char values * @return The resulting string * @since 1.5 */ public String replace(CharSequence target, CharSequence replacement) { ! String trgtStr = target.toString(); String replStr = replacement.toString(); ! int thisLen = length(); ! int trgtLen = trgtStr.length(); ! int replLen = replStr.length(); ! ! if (trgtLen > 0) { ! if (trgtLen == 1 && replLen == 1) { ! return replace(trgtStr.charAt(0), replStr.charAt(0)); ! } ! ! boolean thisIsLatin1 = this.isLatin1(); ! boolean trgtIsLatin1 = trgtStr.isLatin1(); ! boolean replIsLatin1 = replStr.isLatin1(); ! String ret = (thisIsLatin1 && trgtIsLatin1 && replIsLatin1) ! ? StringLatin1.replace(value, thisLen, ! trgtStr.value, trgtLen, ! replStr.value, replLen) ! : StringUTF16.replace(value, thisLen, thisIsLatin1, ! trgtStr.value, trgtLen, trgtIsLatin1, ! replStr.value, replLen, replIsLatin1); ! if (ret != null) { ! return ret; ! } return this; - - } else { // trgtLen == 0 - int resultLen; - try { - resultLen = Math.addExact(thisLen, Math.multiplyExact( - Math.addExact(thisLen, 1), replLen)); - } catch (ArithmeticException ignored) { - throw new OutOfMemoryError(); - } - - StringBuilder sb = new StringBuilder(resultLen); - sb.append(replStr); - for (int i = 0; i < thisLen; ++i) { - sb.append(charAt(i)).append(replStr); - } - return sb.toString(); } } /** * Splits this string around matches of the given * <a href="../util/regex/Pattern.html#sum">regular expression</a>. --- 2153,2183 ---- * @param replacement The replacement sequence of char values * @return The resulting string * @since 1.5 */ public String replace(CharSequence target, CharSequence replacement) { ! String tgtStr = target.toString(); String replStr = replacement.toString(); ! int j = indexOf(tgtStr); ! if (j < 0) { return this; } + int tgtLen = tgtStr.length(); + int tgtLen1 = Math.max(tgtLen, 1); + int thisLen = length(); + + int newLenHint = thisLen - tgtLen + replStr.length(); + if (newLenHint < 0) { + throw new OutOfMemoryError(); + } + StringBuilder sb = new StringBuilder(newLenHint); + int i = 0; + do { + sb.append(this, i, j).append(replStr); + i = j + tgtLen; + } while (j < thisLen && (j = indexOf(tgtStr, j + tgtLen1)) > 0); + return sb.append(this, i, thisLen).toString(); } /** * Splits this string around matches of the given * <a href="../util/regex/Pattern.html#sum">regular expression</a>.
*** 2987,2996 **** --- 2961,2983 ---- * <p> The locale always used is the one returned by {@link * java.util.Locale#getDefault(java.util.Locale.Category) * Locale.getDefault(Locale.Category)} with * {@link java.util.Locale.Category#FORMAT FORMAT} category specified. * + * @implNote + * An invocation of this method may be intrinsified {@link java.lang.compiler.IntrinsicCandidate} + * if the {@code format} string is a constant expression. Intrinsification replaces the method + * invocation with a string concatenation operation. No checks are made during intrinsification + * on the content of the {@code format} string, so an IllegalFormatException is possible at + * run time. + * <p> + * The treatment of subsequent arguments is the same as without intrinsification: arguments that + * are constant expressions are evaluated at compile time, and arguments that are not constant + * expressions are evaluated at run time. (An argument that is a nested invocation of an + * intrinsifiable method may be evaluated at compile time and/or run time, per the compiler's + * usual discretion on when and how to intrinsify.) + * * @param format * A <a href="../util/Formatter.html#syntax">format string</a> * * @param args * Arguments referenced by the format specifiers in the format
*** 3015,3032 **** --- 3002,3033 ---- * @return A formatted string * * @see java.util.Formatter * @since 1.5 */ + @IntrinsicCandidate public static String format(String format, Object... args) { return new Formatter().format(format, args).toString(); } /** * Returns a formatted string using the specified locale, format string, * and arguments. * + * @implNote + * An invocation of this method may be intrinsified {@link java.lang.compiler.IntrinsicCandidate} + * if the {@code format} string is a constant expression. Intrinsification replaces the method + * invocation with a string concatenation operation. No checks are made during intrinsification + * on the content of the {@code format} string, so an IllegalFormatException is possible at + * run time. + * <p> + * The treatment of subsequent arguments is the same as without intrinsification: arguments that + * are constant expressions are evaluated at compile time, and arguments that are not constant + * expressions are evaluated at run time. (An argument that is a nested invocation of an + * intrinsifiable method may be evaluated at compile time and/or run time, per the compiler's + * usual discretion on when and how to intrinsify.) + * * @param l * The {@linkplain java.util.Locale locale} to apply during * formatting. If {@code l} is {@code null} then no localization * is applied. *
*** 3056,3070 **** --- 3057,3180 ---- * @return A formatted string * * @see java.util.Formatter * @since 1.5 */ + @IntrinsicCandidate public static String format(Locale l, String format, Object... args) { return new Formatter(l).format(format, args).toString(); } /** + * Returns a formatted string using this string, as the specified + * <a href="../util/Formatter.html#syntax">format</a>, and + * arguments. + * + * <p> The locale always used is the one returned by {@link + * java.util.Locale#getDefault(java.util.Locale.Category) + * Locale.getDefault(Locale.Category)} with + * {@link java.util.Locale.Category#FORMAT FORMAT} category specified. + * + * @implNote + * An invocation of this method may be intrinsified {@link java.lang.compiler.IntrinsicCandidate} + * if the {@code format} string is a constant expression. Intrinsification replaces the method + * invocation with a string concatenation operation. No checks are made during intrinsification + * on the content of the {@code format} string, so an IllegalFormatException is possible at + * run time. + * <p> + * The treatment of subsequent arguments is the same as without intrinsification: arguments that + * are constant expressions are evaluated at compile time, and arguments that are not constant + * expressions are evaluated at run time. (An argument that is a nested invocation of an + * intrinsifiable method may be evaluated at compile time and/or run time, per the compiler's + * usual discretion on when and how to intrinsify.) + * + * @param args + * Arguments referenced by the format specifiers in the format + * string. If there are more arguments than format specifiers, the + * extra arguments are ignored. The number of arguments is + * variable and may be zero. The maximum number of arguments is + * limited by the maximum dimension of a Java array as defined by + * <cite>The Java&trade; Virtual Machine Specification</cite>. + * The behaviour on a + * {@code null} argument depends on the <a + * href="../util/Formatter.html#syntax">conversion</a>. + * + * @throws java.util.IllegalFormatException + * If a format string contains an illegal syntax, a format + * specifier that is incompatible with the given arguments, + * insufficient arguments given the format string, or other + * illegal conditions. For specification of all possible + * formatting errors, see the <a + * href="../util/Formatter.html#detail">Details</a> section of the + * formatter class specification. + * + * @return A formatted string + * + * @see java.util.Formatter + * + * @since 12 + */ + @IntrinsicCandidate + public String format(Object... args) { + return new Formatter().format(this, args).toString(); + } + + /** + * Returns a formatted string using this string, as the specified + * <a href="../util/Formatter.html#syntax">format</a>, the specified locale, + * and arguments. + * + * @implNote + * An invocation of this method may be intrinsified {@link java.lang.compiler.IntrinsicCandidate} + * if the {@code format} string is a constant expression. Intrinsification replaces the method + * invocation with a string concatenation operation. No checks are made during intrinsification + * on the content of the {@code format} string, so an IllegalFormatException is possible at + * run time. + * <p> + * The treatment of subsequent arguments is the same as without intrinsification: arguments that + * are constant expressions are evaluated at compile time, and arguments that are not constant + * expressions are evaluated at run time. (An argument that is a nested invocation of an + * intrinsifiable method may be evaluated at compile time and/or run time, per the compiler's + * usual discretion on when and how to intrinsify.) + * + * @param l + * The {@linkplain java.util.Locale locale} to apply during + * formatting. If {@code l} is {@code null} then no localization + * is applied. + * + * @param args + * Arguments referenced by the format specifiers in the format + * string. If there are more arguments than format specifiers, the + * extra arguments are ignored. The number of arguments is + * variable and may be zero. The maximum number of arguments is + * limited by the maximum dimension of a Java array as defined by + * <cite>The Java&trade; Virtual Machine Specification</cite>. + * The behaviour on a + * {@code null} argument depends on the + * <a href="../util/Formatter.html#syntax">conversion</a>. + * + * @throws java.util.IllegalFormatException + * If a format string contains an illegal syntax, a format + * specifier that is incompatible with the given arguments, + * insufficient arguments given the format string, or other + * illegal conditions. For specification of all possible + * formatting errors, see the <a + * href="../util/Formatter.html#detail">Details</a> section of the + * formatter class specification + * + * @return A formatted string + * + * @see java.util.Formatter + * + * @since 12 + */ + @IntrinsicCandidate + public String format(Locale l, Object... args) { + return new Formatter(l).format(this, args).toString(); + } + + /** * Returns the string representation of the {@code Object} argument. * * @param obj an {@code Object}. * @return if the argument is {@code null}, then a string equal to * {@code "null"}; otherwise, the value of
< prev index next >