Frames | No Frames |
1: /* String.java -- immutable character sequences; the object of string literals 2: Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 3: Free Software Foundation, Inc. 4: 5: This file is part of GNU Classpath. 6: 7: GNU Classpath is free software; you can redistribute it and/or modify 8: it under the terms of the GNU General Public License as published by 9: the Free Software Foundation; either version 2, or (at your option) 10: any later version. 11: 12: GNU Classpath is distributed in the hope that it will be useful, but 13: WITHOUT ANY WARRANTY; without even the implied warranty of 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15: General Public License for more details. 16: 17: You should have received a copy of the GNU General Public License 18: along with GNU Classpath; see the file COPYING. If not, write to the 19: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20: 02110-1301 USA. 21: 22: Linking this library statically or dynamically with other modules is 23: making a combined work based on this library. Thus, the terms and 24: conditions of the GNU General Public License cover the whole 25: combination. 26: 27: As a special exception, the copyright holders of this library give you 28: permission to link this library with independent modules to produce an 29: executable, regardless of the license terms of these independent 30: modules, and to copy and distribute the resulting executable under 31: terms of your choice, provided that you also meet, for each linked 32: independent module, the terms and conditions of the license of that 33: module. An independent module is a module which is not derived from 34: or based on this library. If you modify this library, you may extend 35: this exception to your version of the library, but you are not 36: obligated to do so. If you do not wish to do so, delete this 37: exception statement from your version. */ 38: 39: 40: package java.lang; 41: 42: import java.io.Serializable; 43: import java.io.UnsupportedEncodingException; 44: import java.lang.Comparable; 45: import java.util.Comparator; 46: import java.util.Locale; 47: import java.util.regex.Pattern; 48: import java.util.regex.PatternSyntaxException; 49: 50: /** 51: * Strings represent an immutable set of characters. All String literals 52: * are instances of this class, and two string literals with the same contents 53: * refer to the same String object. 54: * 55: * <p>This class also includes a number of methods for manipulating the 56: * contents of strings (of course, creating a new object if there are any 57: * changes, as String is immutable). Case mapping relies on Unicode 3.0.0 58: * standards, where some character sequences have a different number of 59: * characters in the uppercase version than the lower case. 60: * 61: * <p>Strings are special, in that they are the only object with an overloaded 62: * operator. When you use '+' with at least one String argument, both 63: * arguments have String conversion performed on them, and another String (not 64: * guaranteed to be unique) results. 65: * 66: * <p>String is special-cased when doing data serialization - rather than 67: * listing the fields of this class, a String object is converted to a string 68: * literal in the object stream. 69: * 70: * @author Paul N. Fisher 71: * @author Eric Blake (ebb9@email.byu.edu) 72: * @author Per Bothner (bothner@cygnus.com) 73: * @since 1.0 74: * @status updated to 1.4 75: */ 76: public final class String implements Serializable, Comparable, CharSequence 77: { 78: // WARNING: String is a CORE class in the bootstrap cycle. See the comments 79: // in vm/reference/java/lang/Runtime for implications of this fact. 80: 81: /** 82: * This is probably not necessary because this class is special cased already 83: * but it will avoid showing up as a discrepancy when comparing SUIDs. 84: */ 85: private static final long serialVersionUID = -6849794470754667710L; 86: 87: /** 88: * This is the object that holds the characters that make up the 89: * String. It might be a char[], or it could be String. It could 90: * even be `this'. The actual characters can't be located using 91: * pure Java code. 92: * @see #boffset 93: */ 94: private Object data; 95: 96: /** 97: * This is a <emph>byte</emph> offset of the actual characters from 98: * the start of the character-holding object. Don't use this field 99: * in Java code. 100: */ 101: private int boffset; 102: 103: /** 104: * Holds the number of characters in value. Package visible for use 105: * by trusted code. 106: */ 107: int count; 108: 109: /** 110: * Caches the result of hashCode(). If this value is zero, the hashcode 111: * is considered uncached (even if 0 is the correct hash value). 112: */ 113: private int cachedHashCode; 114: 115: /** 116: * An implementation for {@link CASE_INSENSITIVE_ORDER}. 117: * This must be {@link Serializable}. The class name is dictated by 118: * compatibility with Sun's JDK. 119: */ 120: private static final class CaseInsensitiveComparator 121: implements Comparator, Serializable 122: { 123: /** 124: * Compatible with JDK 1.2. 125: */ 126: private static final long serialVersionUID = 8575799808933029326L; 127: 128: /** 129: * The default private constructor generates unnecessary overhead. 130: */ 131: CaseInsensitiveComparator() {} 132: 133: /** 134: * Compares to Strings, using 135: * <code>String.compareToIgnoreCase(String)</code>. 136: * 137: * @param o1 the first string 138: * @param o2 the second string 139: * @return < 0, 0, or > 0 depending on the case-insensitive 140: * comparison of the two strings. 141: * @throws NullPointerException if either argument is null 142: * @throws ClassCastException if either argument is not a String 143: * @see #compareToIgnoreCase(String) 144: */ 145: public int compare(Object o1, Object o2) 146: { 147: return ((String) o1).compareToIgnoreCase((String) o2); 148: } 149: } // class CaseInsensitiveComparator 150: 151: /** 152: * A Comparator that uses <code>String.compareToIgnoreCase(String)</code>. 153: * This comparator is {@link Serializable}. Note that it ignores Locale, 154: * for that, you want a Collator. 155: * 156: * @see Collator#compare(String, String) 157: * @since 1.2 158: */ 159: public static final Comparator CASE_INSENSITIVE_ORDER 160: = new CaseInsensitiveComparator(); 161: 162: /** 163: * Creates an empty String (length 0). Unless you really need a new object, 164: * consider using <code>""</code> instead. 165: */ 166: public String() 167: { 168: data = "".data; 169: boffset = 0; 170: count = 0; 171: } 172: 173: /** 174: * Copies the contents of a String to a new String. Since Strings are 175: * immutable, only a shallow copy is performed. 176: * 177: * @param str String to copy 178: * @throws NullPointerException if value is null 179: */ 180: public String(String str) 181: { 182: data = str.data; 183: boffset = str.boffset; 184: count = str.count; 185: cachedHashCode = str.cachedHashCode; 186: } 187: 188: /** 189: * Creates a new String using the character sequence of the char array. 190: * Subsequent changes to data do not affect the String. 191: * 192: * @param data char array to copy 193: * @throws NullPointerException if data is null 194: */ 195: public String(char[] data) 196: { 197: init(data, 0, data.length, false); 198: } 199: 200: /** 201: * Creates a new String using the character sequence of a subarray of 202: * characters. The string starts at offset, and copies count chars. 203: * Subsequent changes to data do not affect the String. 204: * 205: * @param data char array to copy 206: * @param offset position (base 0) to start copying out of data 207: * @param count the number of characters from data to copy 208: * @throws NullPointerException if data is null 209: * @throws IndexOutOfBoundsException if (offset < 0 || count < 0 210: * || offset + count > data.length) 211: * (while unspecified, this is a StringIndexOutOfBoundsException) 212: */ 213: public String(char[] data, int offset, int count) 214: { 215: init(data, offset, count, false); 216: } 217: 218: /** 219: * Creates a new String using an 8-bit array of integer values, starting at 220: * an offset, and copying up to the count. Each character c, using 221: * corresponding byte b, is created in the new String as if by performing: 222: * 223: * <pre> 224: * c = (char) (((hibyte & 0xff) << 8) | (b & 0xff)) 225: * </pre> 226: * 227: * @param ascii array of integer values 228: * @param hibyte top byte of each Unicode character 229: * @param offset position (base 0) to start copying out of ascii 230: * @param count the number of characters from ascii to copy 231: * @throws NullPointerException if ascii is null 232: * @throws IndexOutOfBoundsException if (offset < 0 || count < 0 233: * || offset + count > ascii.length) 234: * (while unspecified, this is a StringIndexOutOfBoundsException) 235: * @see #String(byte[]) 236: * @see #String(byte[], String) 237: * @see #String(byte[], int, int) 238: * @see #String(byte[], int, int, String) 239: * @deprecated use {@link #String(byte[], int, int, String)} to perform 240: * correct encoding 241: */ 242: public String(byte[] ascii, int hibyte, int offset, int count) 243: { 244: init(ascii, hibyte, offset, count); 245: } 246: 247: /** 248: * Creates a new String using an 8-bit array of integer values. Each 249: * character c, using corresponding byte b, is created in the new String 250: * as if by performing: 251: * 252: * <pre> 253: * c = (char) (((hibyte & 0xff) << 8) | (b & 0xff)) 254: * </pre> 255: * 256: * @param ascii array of integer values 257: * @param hibyte top byte of each Unicode character 258: * @throws NullPointerException if ascii is null 259: * @see #String(byte[]) 260: * @see #String(byte[], String) 261: * @see #String(byte[], int, int) 262: * @see #String(byte[], int, int, String) 263: * @see #String(byte[], int, int, int) 264: * @deprecated use {@link #String(byte[], String)} to perform 265: * correct encoding 266: */ 267: public String(byte[] ascii, int hibyte) 268: { 269: init(ascii, hibyte, 0, ascii.length); 270: } 271: 272: /** 273: * Creates a new String using the portion of the byte array starting at the 274: * offset and ending at offset + count. Uses the specified encoding type 275: * to decode the byte array, so the resulting string may be longer or 276: * shorter than the byte array. For more decoding control, use 277: * {@link java.nio.charset.CharsetDecoder}, and for valid character sets, 278: * see {@link java.nio.charset.Charset}. The behavior is not specified if 279: * the decoder encounters invalid characters; this implementation throws 280: * an Error. 281: * 282: * @param data byte array to copy 283: * @param offset the offset to start at 284: * @param count the number of characters in the array to use 285: * @param encoding the name of the encoding to use 286: * @throws NullPointerException if data or encoding is null 287: * @throws IndexOutOfBoundsException if offset or count is incorrect 288: * (while unspecified, this is a StringIndexOutOfBoundsException) 289: * @throws UnsupportedEncodingException if encoding is not found 290: * @throws Error if the decoding fails 291: * @since 1.1 292: */ 293: public String(byte[] data, int offset, int count, String encoding) 294: throws UnsupportedEncodingException 295: { 296: init (data, offset, count, encoding); 297: } 298: 299: /** 300: * Creates a new String using the byte array. Uses the specified encoding 301: * type to decode the byte array, so the resulting string may be longer or 302: * shorter than the byte array. For more decoding control, use 303: * {@link java.nio.charset.CharsetDecoder}, and for valid character sets, 304: * see {@link java.nio.charset.Charset}. The behavior is not specified if 305: * the decoder encounters invalid characters; this implementation throws 306: * an Error. 307: * 308: * @param data byte array to copy 309: * @param encoding the name of the encoding to use 310: * @throws NullPointerException if data or encoding is null 311: * @throws UnsupportedEncodingException if encoding is not found 312: * @throws Error if the decoding fails 313: * @see #String(byte[], int, int, String) 314: * @since 1.1 315: */ 316: public String(byte[] data, String encoding) 317: throws UnsupportedEncodingException 318: { 319: this(data, 0, data.length, encoding); 320: } 321: 322: /** 323: * Creates a new String using the portion of the byte array starting at the 324: * offset and ending at offset + count. Uses the encoding of the platform's 325: * default charset, so the resulting string may be longer or shorter than 326: * the byte array. For more decoding control, use 327: * {@link java.nio.charset.CharsetDecoder}. The behavior is not specified 328: * if the decoder encounters invalid characters; this implementation throws 329: * an Error. 330: * 331: * @param data byte array to copy 332: * @param offset the offset to start at 333: * @param count the number of characters in the array to use 334: * @throws NullPointerException if data is null 335: * @throws IndexOutOfBoundsException if offset or count is incorrect 336: * @throws Error if the decoding fails 337: * @see #String(byte[], int, int, String) 338: * @since 1.1 339: */ 340: public String(byte[] data, int offset, int count) 341: { 342: try 343: { 344: init (data, offset, count, 345: System.getProperty("file.encoding", "8859_1")); 346: } 347: catch (UnsupportedEncodingException x1) 348: { 349: // Maybe the default encoding is bad. 350: try 351: { 352: init (data, offset, count, "8859_1"); 353: } 354: catch (UnsupportedEncodingException x2) 355: { 356: // We know this can't happen. 357: } 358: } 359: } 360: 361: /** 362: * Creates a new String using the byte array. Uses the encoding of the 363: * platform's default charset, so the resulting string may be longer or 364: * shorter than the byte array. For more decoding control, use 365: * {@link java.nio.charset.CharsetDecoder}. The behavior is not specified 366: * if the decoder encounters invalid characters; this implementation throws 367: * an Error. 368: * 369: * @param data byte array to copy 370: * @throws NullPointerException if data is null 371: * @throws Error if the decoding fails 372: * @see #String(byte[], int, int) 373: * @see #String(byte[], int, int, String) 374: * @since 1.1 375: */ 376: public String(byte[] data) 377: { 378: this(data, 0, data.length); 379: } 380: 381: /** 382: * Creates a new String using the character sequence represented by 383: * the StringBuffer. Subsequent changes to buf do not affect the String. 384: * 385: * @param buffer StringBuffer to copy 386: * @throws NullPointerException if buffer is null 387: */ 388: public String(StringBuffer buffer) 389: { 390: synchronized (buffer) 391: { 392: // Share unless buffer is 3/4 empty. 393: boolean should_copy = ((buffer.count << 2) < buffer.value.length); 394: if (! should_copy) 395: buffer.shared = true; 396: init (buffer.value, 0, buffer.count, ! should_copy); 397: } 398: } 399: 400: /** 401: * Creates a new String using the character sequence represented by 402: * the StringBuilder. Subsequent changes to buf do not affect the String. 403: * 404: * @param buffer StringBuilder to copy 405: * @throws NullPointerException if buffer is null 406: */ 407: public String(StringBuilder buffer) 408: { 409: this(buffer.value, 0, buffer.count); 410: } 411: 412: /** 413: * Special constructor which can share an array when safe to do so. 414: * 415: * @param data the characters to copy 416: * @param offset the location to start from 417: * @param count the number of characters to use 418: * @param dont_copy true if the array is trusted, and need not be copied 419: * @throws NullPointerException if chars is null 420: * @throws StringIndexOutOfBoundsException if bounds check fails 421: */ 422: String(char[] data, int offset, int count, boolean dont_copy) 423: { 424: init(data, offset, count, dont_copy); 425: } 426: 427: // This is used by gnu.gcj.runtime.StringBuffer, so it must have 428: // package-private protection. It is accessed via CNI and so avoids 429: // ordinary protection mechanisms. 430: String(gnu.gcj.runtime.StringBuffer buffer) 431: { 432: // No need to synchronize or mark the buffer, since we know it is 433: // only used once. 434: init (buffer); 435: } 436: 437: /** 438: * Returns the number of characters contained in this String. 439: * 440: * @return the length of this String 441: */ 442: public int length() 443: { 444: return count; 445: } 446: 447: /** 448: * Returns the character located at the specified index within this String. 449: * 450: * @param index position of character to return (base 0) 451: * @return character located at position index 452: * @throws IndexOutOfBoundsException if index < 0 || index >= length() 453: * (while unspecified, this is a StringIndexOutOfBoundsException) 454: */ 455: public native char charAt(int index); 456: 457: /** 458: * Get the code point at the specified index. This is like #charAt(int), 459: * but if the character is the start of a surrogate pair, and the 460: * following character completes the pair, then the corresponding 461: * supplementary code point is returned. 462: * @param index the index of the codepoint to get, starting at 0 463: * @return the codepoint at the specified index 464: * @throws IndexOutOfBoundsException if index is negative or >= length() 465: * @since 1.5 466: */ 467: public synchronized int codePointAt(int index) 468: { 469: // Use the CharSequence overload as we get better range checking 470: // this way. 471: return Character.codePointAt(this, index); 472: } 473: 474: /** 475: * Get the code point before the specified index. This is like 476: * #codePointAt(int), but checks the characters at <code>index-1</code> and 477: * <code>index-2</code> to see if they form a supplementary code point. 478: * @param index the index just past the codepoint to get, starting at 0 479: * @return the codepoint at the specified index 480: * @throws IndexOutOfBoundsException if index is negative or >= length() 481: * (while unspecified, this is a StringIndexOutOfBoundsException) 482: * @since 1.5 483: */ 484: public synchronized int codePointBefore(int index) 485: { 486: // Use the CharSequence overload as we get better range checking 487: // this way. 488: return Character.codePointBefore(this, index); 489: } 490: 491: /** 492: * Copies characters from this String starting at a specified start index, 493: * ending at a specified stop index, to a character array starting at 494: * a specified destination begin index. 495: * 496: * @param srcBegin index to begin copying characters from this String 497: * @param srcEnd index after the last character to be copied from this String 498: * @param dst character array which this String is copied into 499: * @param dstBegin index to start writing characters into dst 500: * @throws NullPointerException if dst is null 501: * @throws IndexOutOfBoundsException if any indices are out of bounds 502: * (while unspecified, source problems cause a 503: * StringIndexOutOfBoundsException, and dst problems cause an 504: * ArrayIndexOutOfBoundsException) 505: */ 506: public native void getChars(int srcBegin, int srcEnd, 507: char[] dst, int dstBegin); 508: 509: /** 510: * Copies the low byte of each character from this String starting at a 511: * specified start index, ending at a specified stop index, to a byte array 512: * starting at a specified destination begin index. 513: * 514: * @param srcBegin index to being copying characters from this String 515: * @param srcEnd index after the last character to be copied from this String 516: * @param dst byte array which each low byte of this String is copied into 517: * @param dstBegin index to start writing characters into dst 518: * @throws NullPointerException if dst is null and copy length is non-zero 519: * @throws IndexOutOfBoundsException if any indices are out of bounds 520: * (while unspecified, source problems cause a 521: * StringIndexOutOfBoundsException, and dst problems cause an 522: * ArrayIndexOutOfBoundsException) 523: * @see #getBytes() 524: * @see #getBytes(String) 525: * @deprecated use {@link #getBytes()}, which uses a char to byte encoder 526: */ 527: public native void getBytes(int srcBegin, int srcEnd, 528: byte[] dst, int dstBegin); 529: 530: /** 531: * Converts the Unicode characters in this String to a byte array. Uses the 532: * specified encoding method, so the result may be longer or shorter than 533: * the String. For more encoding control, use 534: * {@link java.nio.charset.CharsetEncoder}, and for valid character sets, 535: * see {@link java.nio.charset.Charset}. The behavior is not specified if 536: * the encoder encounters a problem; this implementation returns null. 537: * 538: * @param enc encoding name 539: * @return the resulting byte array, or null on a problem 540: * @throws NullPointerException if enc is null 541: * @throws UnsupportedEncodingException if encoding is not supported 542: * @since 1.1 543: */ 544: public native byte[] getBytes(String enc) 545: throws UnsupportedEncodingException; 546: 547: /** 548: * Converts the Unicode characters in this String to a byte array. Uses the 549: * encoding of the platform's default charset, so the result may be longer 550: * or shorter than the String. For more encoding control, use 551: * {@link java.nio.charset.CharsetEncoder}. The behavior is not specified if 552: * the encoder encounters a problem; this implementation returns null. 553: * 554: * @return the resulting byte array, or null on a problem 555: * @since 1.1 556: */ 557: public byte[] getBytes() 558: { 559: try 560: { 561: return getBytes (System.getProperty("file.encoding", "8859_1")); 562: } 563: catch (UnsupportedEncodingException x) 564: { 565: // This probably shouldn't happen, but could if file.encoding 566: // is somehow changed to a value we don't understand. 567: try 568: { 569: return getBytes ("8859_1"); 570: } 571: catch (UnsupportedEncodingException x2) 572: { 573: // This really shouldn't happen, because the 8859_1 574: // encoding should always be available. 575: throw new InternalError ("couldn't find 8859_1 encoder"); 576: } 577: } 578: } 579: 580: /** 581: * Predicate which compares anObject to this. This is true only for Strings 582: * with the same character sequence. 583: * 584: * @param anObject the object to compare 585: * @return true if anObject is semantically equal to this 586: * @see #compareTo(String) 587: * @see #equalsIgnoreCase(String) 588: */ 589: public native boolean equals(Object anObject); 590: 591: /** 592: * Compares the given StringBuffer to this String. This is true if the 593: * StringBuffer has the same content as this String at this moment. 594: * 595: * @param buffer the StringBuffer to compare to 596: * @return true if StringBuffer has the same character sequence 597: * @throws NullPointerException if the given StringBuffer is null 598: * @since 1.4 599: */ 600: public native boolean contentEquals(StringBuffer buffer); 601: 602: /** 603: * Compares the given CharSequence to this String. This is true if 604: * the CharSequence has the same content as this String at this 605: * moment. 606: * 607: * @param seq the CharSequence to compare to 608: * @return true if CharSequence has the same character sequence 609: * @throws NullPointerException if the given CharSequence is null 610: * @since 1.5 611: */ 612: public native boolean contentEquals(CharSequence seq); 613: 614: /** 615: * Compares a String to this String, ignoring case. This does not handle 616: * multi-character capitalization exceptions; instead the comparison is 617: * made on a character-by-character basis, and is true if:<br><ul> 618: * <li><code>c1 == c2</code></li> 619: * <li><code>Character.toUpperCase(c1) 620: * == Character.toUpperCase(c2)</code></li> 621: * <li><code>Character.toLowerCase(c1) 622: * == Character.toLowerCase(c2)</code></li> 623: * </ul> 624: * 625: * @param anotherString String to compare to this String 626: * @return true if anotherString is equal, ignoring case 627: * @see #equals(Object) 628: * @see Character#toUpperCase(char) 629: * @see Character#toLowerCase(char) 630: */ 631: public native boolean equalsIgnoreCase(String anotherString); 632: 633: /** 634: * Compares this String and another String (case sensitive, 635: * lexicographically). The result is less than 0 if this string sorts 636: * before the other, 0 if they are equal, and greater than 0 otherwise. 637: * After any common starting sequence is skipped, the result is 638: * <code>this.charAt(k) - anotherString.charAt(k)</code> if both strings 639: * have characters remaining, or 640: * <code>this.length() - anotherString.length()</code> if one string is 641: * a subsequence of the other. 642: * 643: * @param anotherString the String to compare against 644: * @return the comparison 645: * @throws NullPointerException if anotherString is null 646: */ 647: public native int compareTo(String anotherString); 648: 649: /** 650: * Behaves like <code>compareTo(java.lang.String)</code> unless the Object 651: * is not a <code>String</code>. Then it throws a 652: * <code>ClassCastException</code>. 653: * 654: * @param o the object to compare against 655: * @return the comparison 656: * @throws NullPointerException if o is null 657: * @throws ClassCastException if o is not a <code>String</code> 658: * @since 1.2 659: */ 660: public int compareTo(Object o) 661: { 662: return compareTo((String) o); 663: } 664: 665: /** 666: * Compares this String and another String (case insensitive). This 667: * comparison is <em>similar</em> to equalsIgnoreCase, in that it ignores 668: * locale and multi-characater capitalization, and compares characters 669: * after performing 670: * <code>Character.toLowerCase(Character.toUpperCase(c))</code> on each 671: * character of the string. This is unsatisfactory for locale-based 672: * comparison, in which case you should use {@link java.text.Collator}. 673: * 674: * @param str the string to compare against 675: * @return the comparison 676: * @see Collator#compare(String, String) 677: * @since 1.2 678: */ 679: public int compareToIgnoreCase(String str) 680: { 681: return this.toUpperCase().toLowerCase().compareTo( 682: str.toUpperCase().toLowerCase()); 683: } 684: 685: /** 686: * Predicate which determines if this String matches another String 687: * starting at a specified offset for each String and continuing 688: * for a specified length. Indices out of bounds are harmless, and give 689: * a false result. 690: * 691: * @param toffset index to start comparison at for this String 692: * @param other String to compare region to this String 693: * @param ooffset index to start comparison at for other 694: * @param len number of characters to compare 695: * @return true if regions match (case sensitive) 696: * @throws NullPointerException if other is null 697: */ 698: public native boolean regionMatches(int toffset, 699: String other, int ooffset, int len); 700: 701: /** 702: * Predicate which determines if this String matches another String 703: * starting at a specified offset for each String and continuing 704: * for a specified length, optionally ignoring case. Indices out of bounds 705: * are harmless, and give a false result. Case comparisons are based on 706: * <code>Character.toLowerCase()</code> and 707: * <code>Character.toUpperCase()</code>, not on multi-character 708: * capitalization expansions. 709: * 710: * @param ignoreCase true if case should be ignored in comparision 711: * @param toffset index to start comparison at for this String 712: * @param other String to compare region to this String 713: * @param oofset index to start comparison at for other 714: * @param len number of characters to compare 715: * @return true if regions match, false otherwise 716: * @throws NullPointerException if other is null 717: */ 718: public native boolean regionMatches(boolean ignoreCase, int toffset, 719: String other, int ooffset, int len); 720: 721: /** 722: * Predicate which determines if this String contains the given prefix, 723: * beginning comparison at toffset. The result is false if toffset is 724: * negative or greater than this.length(), otherwise it is the same as 725: * <code>this.substring(toffset).startsWith(prefix)</code>. 726: * 727: * @param prefix String to compare 728: * @param toffset offset for this String where comparison starts 729: * @return true if this String starts with prefix 730: * @throws NullPointerException if prefix is null 731: * @see #regionMatches(boolean, int, String, int, int) 732: */ 733: public native boolean startsWith(String prefix, int toffset); 734: 735: /** 736: * Predicate which determines if this String starts with a given prefix. 737: * If the prefix is an empty String, true is returned. 738: * 739: * @param prefix String to compare 740: * @return true if this String starts with the prefix 741: * @throws NullPointerException if prefix is null 742: * @see #startsWith(String, int) 743: */ 744: public boolean startsWith(String prefix) 745: { 746: return startsWith (prefix, 0); 747: } 748: 749: /** 750: * Predicate which determines if this String ends with a given suffix. 751: * If the suffix is an empty String, true is returned. 752: * 753: * @param suffix String to compare 754: * @return true if this String ends with the suffix 755: * @throws NullPointerException if suffix is null 756: * @see #regionMatches(boolean, int, String, int, int) 757: */ 758: public boolean endsWith(String suffix) 759: { 760: return regionMatches (this.count - suffix.count, suffix, 0, suffix.count); 761: } 762: 763: /** 764: * Computes the hashcode for this String. This is done with int arithmetic, 765: * where ** represents exponentiation, by this formula:<br> 766: * <code>s[0]*31**(n-1) + s[1]*31**(n-2) + ... + s[n-1]</code>. 767: * 768: * @return hashcode value of this String 769: */ 770: public native int hashCode(); 771: 772: /** 773: * Finds the first instance of a character in this String. 774: * 775: * @param ch character to find 776: * @return location (base 0) of the character, or -1 if not found 777: */ 778: public int indexOf(int ch) 779: { 780: return indexOf(ch, 0); 781: } 782: 783: /** 784: * Finds the first instance of a character in this String, starting at 785: * a given index. If starting index is less than 0, the search 786: * starts at the beginning of this String. If the starting index 787: * is greater than the length of this String, -1 is returned. 788: * 789: * @param ch character to find 790: * @param fromIndex index to start the search 791: * @return location (base 0) of the character, or -1 if not found 792: */ 793: public native int indexOf(int ch, int fromIndex); 794: 795: /** 796: * Finds the last instance of a character in this String. 797: * 798: * @param ch character to find 799: * @return location (base 0) of the character, or -1 if not found 800: */ 801: public int lastIndexOf(int ch) 802: { 803: return lastIndexOf(ch, count - 1); 804: } 805: 806: /** 807: * Finds the last instance of a character in this String, starting at 808: * a given index. If starting index is greater than the maximum valid 809: * index, then the search begins at the end of this String. If the 810: * starting index is less than zero, -1 is returned. 811: * 812: * @param ch character to find 813: * @param fromIndex index to start the search 814: * @return location (base 0) of the character, or -1 if not found 815: */ 816: public native int lastIndexOf(int ch, int fromIndex); 817: 818: /** 819: * Finds the first instance of a String in this String. 820: * 821: * @param str String to find 822: * @return location (base 0) of the String, or -1 if not found 823: * @throws NullPointerException if str is null 824: */ 825: public int indexOf(String str) 826: { 827: return indexOf(str, 0); 828: } 829: 830: /** 831: * Finds the first instance of a String in this String, starting at 832: * a given index. If starting index is less than 0, the search 833: * starts at the beginning of this String. If the starting index 834: * is greater than the length of this String, -1 is returned. 835: * 836: * @param str String to find 837: * @param fromIndex index to start the search 838: * @return location (base 0) of the String, or -1 if not found 839: * @throws NullPointerException if str is null 840: */ 841: public native int indexOf(String str, int fromIndex); 842: 843: /** 844: * Finds the last instance of a String in this String. 845: * 846: * @param str String to find 847: * @return location (base 0) of the String, or -1 if not found 848: * @throws NullPointerException if str is null 849: */ 850: public int lastIndexOf(String str) 851: { 852: return lastIndexOf(str, count - str.count); 853: } 854: 855: /** 856: * Finds the last instance of a String in this String, starting at 857: * a given index. If starting index is greater than the maximum valid 858: * index, then the search begins at the end of this String. If the 859: * starting index is less than zero, -1 is returned. 860: * 861: * @param str String to find 862: * @param fromIndex index to start the search 863: * @return location (base 0) of the String, or -1 if not found 864: * @throws NullPointerException if str is null 865: */ 866: public int lastIndexOf(String str, int fromIndex) 867: { 868: if (fromIndex >= count) 869: fromIndex = count - str.count; 870: for (;; --fromIndex) 871: { 872: if (fromIndex < 0) 873: return -1; 874: if (startsWith(str, fromIndex)) 875: return fromIndex; 876: } 877: } 878: 879: /** 880: * Creates a substring of this String, starting at a specified index 881: * and ending at the end of this String. 882: * 883: * @param begin index to start substring (base 0) 884: * @return new String which is a substring of this String 885: * @throws IndexOutOfBoundsException if begin < 0 || begin > length() 886: * (while unspecified, this is a StringIndexOutOfBoundsException) 887: */ 888: public String substring(int begin) 889: { 890: return substring(begin, count); 891: } 892: 893: /** 894: * Creates a substring of this String, starting at a specified index 895: * and ending at one character before a specified index. 896: * 897: * @param begin index to start substring (inclusive, base 0) 898: * @param end index to end at (exclusive) 899: * @return new String which is a substring of this String 900: * @throws IndexOutOfBoundsException if begin < 0 || end > length() 901: * || begin > end (while unspecified, this is a 902: * StringIndexOutOfBoundsException) 903: */ 904: public native String substring(int begin, int end); 905: 906: /** 907: * Creates a substring of this String, starting at a specified index 908: * and ending at one character before a specified index. This behaves like 909: * <code>substring(begin, end)</code>. 910: * 911: * @param begin index to start substring (inclusive, base 0) 912: * @param end index to end at (exclusive) 913: * @return new String which is a substring of this String 914: * @throws IndexOutOfBoundsException if begin < 0 || end > length() 915: * || begin > end 916: * @since 1.4 917: */ 918: public CharSequence subSequence(int begin, int end) 919: { 920: return substring(begin, end); 921: } 922: 923: /** 924: * Concatenates a String to this String. This results in a new string unless 925: * one of the two originals is "". 926: * 927: * @param str String to append to this String 928: * @return newly concatenated String 929: * @throws NullPointerException if str is null 930: */ 931: public native String concat(String str); 932: 933: /** 934: * Replaces every instance of a character in this String with a new 935: * character. If no replacements occur, this is returned. 936: * 937: * @param oldChar the old character to replace 938: * @param newChar the new character 939: * @return new String with all instances of oldChar replaced with newChar 940: */ 941: public native String replace(char oldChar, char newChar); 942: 943: /** 944: * Test if this String matches a regular expression. This is shorthand for 945: * <code>{@link Pattern}.matches(regex, this)</code>. 946: * 947: * @param regex the pattern to match 948: * @return true if the pattern matches 949: * @throws NullPointerException if regex is null 950: * @throws PatternSyntaxException if regex is invalid 951: * @see Pattern#matches(String, CharSequence) 952: * @since 1.4 953: */ 954: public boolean matches(String regex) 955: { 956: return Pattern.matches(regex, this); 957: } 958: 959: /** 960: * Replaces the first substring match of the regular expression with a 961: * given replacement. This is shorthand for <code>{@link Pattern} 962: * .compile(regex).matcher(this).replaceFirst(replacement)</code>. 963: * 964: * @param regex the pattern to match 965: * @param replacement the replacement string 966: * @return the modified string 967: * @throws NullPointerException if regex or replacement is null 968: * @throws PatternSyntaxException if regex is invalid 969: * @see #replaceAll(String, String) 970: * @see Pattern#compile(String) 971: * @see Pattern#matcher(CharSequence) 972: * @see Matcher#replaceFirst(String) 973: * @since 1.4 974: */ 975: public String replaceFirst(String regex, String replacement) 976: { 977: return Pattern.compile(regex).matcher(this).replaceFirst(replacement); 978: } 979: 980: /** 981: * Replaces all matching substrings of the regular expression with a 982: * given replacement. This is shorthand for <code>{@link Pattern} 983: * .compile(regex).matcher(this).replaceAll(replacement)</code>. 984: * 985: * @param regex the pattern to match 986: * @param replacement the replacement string 987: * @return the modified string 988: * @throws NullPointerException if regex or replacement is null 989: * @throws PatternSyntaxException if regex is invalid 990: * @see #replaceFirst(String, String) 991: * @see Pattern#compile(String) 992: * @see Pattern#matcher(CharSequence) 993: * @see Matcher#replaceAll(String) 994: * @since 1.4 995: */ 996: public String replaceAll(String regex, String replacement) 997: { 998: return Pattern.compile(regex).matcher(this).replaceAll(replacement); 999: } 1000: 1001: /** 1002: * Split this string around the matches of a regular expression. Each 1003: * element of the returned array is the largest block of characters not 1004: * terminated by the regular expression, in the order the matches are found. 1005: * 1006: * <p>The limit affects the length of the array. If it is positive, the 1007: * array will contain at most n elements (n - 1 pattern matches). If 1008: * negative, the array length is unlimited, but there can be trailing empty 1009: * entries. if 0, the array length is unlimited, and trailing empty entries 1010: * are discarded. 1011: * 1012: * <p>For example, splitting "boo:and:foo" yields:<br> 1013: * <table border=0> 1014: * <th><td>Regex</td> <td>Limit</td> <td>Result</td></th> 1015: * <tr><td>":"</td> <td>2</td> <td>{ "boo", "and:foo" }</td></tr> 1016: * <tr><td>":"</td> <td>t</td> <td>{ "boo", "and", "foo" }</td></tr> 1017: * <tr><td>":"</td> <td>-2</td> <td>{ "boo", "and", "foo" }</td></tr> 1018: * <tr><td>"o"</td> <td>5</td> <td>{ "b", "", ":and:f", "", "" }</td></tr> 1019: * <tr><td>"o"</td> <td>-2</td> <td>{ "b", "", ":and:f", "", "" }</td></tr> 1020: * <tr><td>"o"</td> <td>0</td> <td>{ "b", "", ":and:f" }</td></tr> 1021: * </table> 1022: * 1023: * <p>This is shorthand for 1024: * <code>{@link Pattern}.compile(regex).split(this, limit)</code>. 1025: * 1026: * @param regex the pattern to match 1027: * @param limit the limit threshold 1028: * @return the array of split strings 1029: * @throws NullPointerException if regex or replacement is null 1030: * @throws PatternSyntaxException if regex is invalid 1031: * @see Pattern#compile(String) 1032: * @see Pattern#split(CharSequence, int) 1033: * @since 1.4 1034: */ 1035: public String[] split(String regex, int limit) 1036: { 1037: return Pattern.compile(regex).split(this, limit); 1038: } 1039: 1040: /** 1041: * Split this string around the matches of a regular expression. Each 1042: * element of the returned array is the largest block of characters not 1043: * terminated by the regular expression, in the order the matches are found. 1044: * The array length is unlimited, and trailing empty entries are discarded, 1045: * as though calling <code>split(regex, 0)</code>. 1046: * 1047: * @param regex the pattern to match 1048: * @return the array of split strings 1049: * @throws NullPointerException if regex or replacement is null 1050: * @throws PatternSyntaxException if regex is invalid 1051: * @see #split(String, int) 1052: * @see Pattern#compile(String) 1053: * @see Pattern#split(CharSequence, int) 1054: * @since 1.4 1055: */ 1056: public String[] split(String regex) 1057: { 1058: return Pattern.compile(regex).split(this, 0); 1059: } 1060: 1061: /** 1062: * Lowercases this String according to a particular locale. This uses 1063: * Unicode's special case mappings, as applied to the given Locale, so the 1064: * resulting string may be a different length. 1065: * 1066: * @param loc locale to use 1067: * @return new lowercased String, or this if no characters were lowercased 1068: * @throws NullPointerException if loc is null 1069: * @see #toUpperCase(Locale) 1070: * @since 1.1 1071: */ 1072: public native String toLowerCase(Locale locale); 1073: 1074: /** 1075: * Lowercases this String. This uses Unicode's special case mappings, as 1076: * applied to the platform's default Locale, so the resulting string may 1077: * be a different length. 1078: * 1079: * @return new lowercased String, or this if no characters were lowercased 1080: * @see #toLowerCase(Locale) 1081: * @see #toUpperCase() 1082: */ 1083: public String toLowerCase() 1084: { 1085: // The JDK is a bit confused about what to do here. If we pass in 1086: // the default Locale then special Locale handling might be 1087: // invoked. However, the docs also say that Character.toLowerCase 1088: // rules here. We go with the latter. 1089: return toLowerCase (null); 1090: } 1091: 1092: /** 1093: * Uppercases this String according to a particular locale. This uses 1094: * Unicode's special case mappings, as applied to the given Locale, so the 1095: * resulting string may be a different length. 1096: * 1097: * @param loc locale to use 1098: * @return new uppercased String, or this if no characters were uppercased 1099: * @throws NullPointerException if loc is null 1100: * @see #toLowerCase(Locale) 1101: * @since 1.1 1102: */ 1103: public native String toUpperCase(Locale locale); 1104: 1105: /** 1106: * Uppercases this String. This uses Unicode's special case mappings, as 1107: * applied to the platform's default Locale, so the resulting string may 1108: * be a different length. 1109: * 1110: * @return new uppercased String, or this if no characters were uppercased 1111: * @see #toUpperCase(Locale) 1112: * @see #toLowerCase() 1113: */ 1114: public String toUpperCase() 1115: { 1116: // The JDK is a bit confused about what to do here. If we pass in 1117: // the default Locale then special Locale handling might be 1118: // invoked. However, the docs also say that Character.toLowerCase 1119: // rules here. We go with the latter. 1120: return toUpperCase (null); 1121: } 1122: 1123: /** 1124: * Trims all characters less than or equal to <code>'\u0020'</code> 1125: * (<code>' '</code>) from the beginning and end of this String. This 1126: * includes many, but not all, ASCII control characters, and all 1127: * {@link Character#whitespace(char)}. 1128: * 1129: * @return new trimmed String, or this if nothing trimmed 1130: */ 1131: public native String trim(); 1132: 1133: /** 1134: * Returns this, as it is already a String! 1135: * 1136: * @return this 1137: */ 1138: public String toString() 1139: { 1140: return this; 1141: } 1142: 1143: /** 1144: * Copies the contents of this String into a character array. Subsequent 1145: * changes to the array do not affect the String. 1146: * 1147: * @return character array copying the String 1148: */ 1149: public native char[] toCharArray(); 1150: 1151: /** 1152: * Returns a String representation of an Object. This is "null" if the 1153: * object is null, otherwise it is <code>obj.toString()</code> (which 1154: * can be null). 1155: * 1156: * @param obj the Object 1157: * @return the string conversion of obj 1158: */ 1159: public static String valueOf(Object obj) 1160: { 1161: return obj == null ? "null" : obj.toString(); 1162: } 1163: 1164: /** 1165: * Returns a String representation of a character array. Subsequent 1166: * changes to the array do not affect the String. 1167: * 1168: * @param data the character array 1169: * @return a String containing the same character sequence as data 1170: * @throws NullPointerException if data is null 1171: * @see #valueOf(char[], int, int) 1172: * @see #String(char[]) 1173: */ 1174: public static String valueOf(char[] data) 1175: { 1176: return valueOf (data, 0, data.length); 1177: } 1178: 1179: /** 1180: * Returns a String representing the character sequence of the char array, 1181: * starting at the specified offset, and copying chars up to the specified 1182: * count. Subsequent changes to the array do not affect the String. 1183: * 1184: * @param data character array 1185: * @param offset position (base 0) to start copying out of data 1186: * @param count the number of characters from data to copy 1187: * @return String containing the chars from data[offset..offset+count] 1188: * @throws NullPointerException if data is null 1189: * @throws IndexOutOfBoundsException if (offset < 0 || count < 0 1190: * || offset + count > data.length) 1191: * (while unspecified, this is a StringIndexOutOfBoundsException) 1192: * @see #String(char[], int, int) 1193: */ 1194: public static native String valueOf(char[] data, int offset, int count); 1195: 1196: /** 1197: * Returns a String representing the character sequence of the char array, 1198: * starting at the specified offset, and copying chars up to the specified 1199: * count. Subsequent changes to the array do not affect the String. 1200: * 1201: * @param data character array 1202: * @param offset position (base 0) to start copying out of data 1203: * @param count the number of characters from data to copy 1204: * @return String containing the chars from data[offset..offset+count] 1205: * @throws NullPointerException if data is null 1206: * @throws IndexOutOfBoundsException if (offset < 0 || count < 0 1207: * || offset + count > data.length) 1208: * (while unspecified, this is a StringIndexOutOfBoundsException) 1209: * @see #String(char[], int, int) 1210: */ 1211: public static String copyValueOf(char[] data, int offset, int count) 1212: { 1213: String r = new String (); 1214: r.init(data, offset, count, false); 1215: return r; 1216: } 1217: 1218: /** 1219: * Returns a String representation of a character array. Subsequent 1220: * changes to the array do not affect the String. 1221: * 1222: * @param data the character array 1223: * @return a String containing the same character sequence as data 1224: * @throws NullPointerException if data is null 1225: * @see #copyValueOf(char[], int, int) 1226: * @see #String(char[]) 1227: */ 1228: public static String copyValueOf(char[] data) 1229: { 1230: return copyValueOf (data, 0, data.length); 1231: } 1232: 1233: /** 1234: * Returns a String representing a boolean. 1235: * 1236: * @param b the boolean 1237: * @return "true" if b is true, else "false" 1238: */ 1239: public static String valueOf(boolean b) 1240: { 1241: return b ? "true" : "false"; 1242: } 1243: 1244: /** 1245: * Returns a String representing a character. 1246: * 1247: * @param c the character 1248: * @return String containing the single character c 1249: */ 1250: public static native String valueOf(char c); 1251: 1252: /** 1253: * Returns a String representing an integer. 1254: * 1255: * @param i the integer 1256: * @return String containing the integer in base 10 1257: * @see Integer#toString(int) 1258: */ 1259: public static native String valueOf(int i); 1260: 1261: /** 1262: * Returns a String representing a long. 1263: * 1264: * @param l the long 1265: * @return String containing the long in base 10 1266: * @see Long#toString(long) 1267: */ 1268: public static String valueOf(long l) 1269: { 1270: return Long.toString(l); 1271: } 1272: 1273: /** 1274: * Returns a String representing a float. 1275: * 1276: * @param f the float 1277: * @return String containing the float 1278: * @see Float#toString(float) 1279: */ 1280: public static String valueOf(float f) 1281: { 1282: return Float.toString(f); 1283: } 1284: 1285: /** 1286: * Returns a String representing a double. 1287: * 1288: * @param d the double 1289: * @return String containing the double 1290: * @see Double#toString(double) 1291: */ 1292: public static String valueOf(double d) 1293: { 1294: return Double.toString(d); 1295: } 1296: 1297: /** 1298: * Fetches this String from the intern hashtable. If two Strings are 1299: * considered equal, by the equals() method, then intern() will return the 1300: * same String instance. ie. if (s1.equals(s2)) then 1301: * (s1.intern() == s2.intern()). All string literals and string-valued 1302: * constant expressions are already interned. 1303: * 1304: * @return the interned String 1305: */ 1306: public native String intern(); 1307: 1308: /** 1309: * Return the number of code points between two indices in the 1310: * <code>String</code>. An unpaired surrogate counts as a 1311: * code point for this purpose. Characters outside the indicated 1312: * range are not examined, even if the range ends in the middle of a 1313: * surrogate pair. 1314: * 1315: * @param start the starting index 1316: * @param end one past the ending index 1317: * @return the number of code points 1318: * @since 1.5 1319: */ 1320: public synchronized int codePointCount(int start, int end) 1321: { 1322: if (start < 0 || end > count || start > end) 1323: throw new StringIndexOutOfBoundsException(); 1324: 1325: int count = 0; 1326: while (start < end) 1327: { 1328: char base = charAt(start); 1329: if (base < Character.MIN_HIGH_SURROGATE 1330: || base > Character.MAX_HIGH_SURROGATE 1331: || start == end 1332: || start == count 1333: || charAt(start + 1) < Character.MIN_LOW_SURROGATE 1334: || charAt(start + 1) > Character.MAX_LOW_SURROGATE) 1335: { 1336: // Nothing. 1337: } 1338: else 1339: { 1340: // Surrogate pair. 1341: ++start; 1342: } 1343: ++start; 1344: ++count; 1345: } 1346: return count; 1347: } 1348: 1349: /** 1350: * Returns true iff this String contains the sequence of Characters 1351: * described in s. 1352: * @param s the CharSequence 1353: * @return true iff this String contains s 1354: * 1355: * @since 1.5 1356: */ 1357: public boolean contains (CharSequence s) 1358: { 1359: return this.indexOf(s.toString()) != -1; 1360: } 1361: 1362: /** 1363: * Returns a string that is this string with all instances of the sequence 1364: * represented by <code>target</code> replaced by the sequence in 1365: * <code>replacement</code>. 1366: * @param target the sequence to be replaced 1367: * @param replacement the sequence used as the replacement 1368: * @return the string constructed as above 1369: */ 1370: public String replace (CharSequence target, CharSequence replacement) 1371: { 1372: String targetString = target.toString(); 1373: String replaceString = replacement.toString(); 1374: int targetLength = target.length(); 1375: int replaceLength = replacement.length(); 1376: 1377: int startPos = this.indexOf(targetString); 1378: StringBuilder result = new StringBuilder(this); 1379: while (startPos != -1) 1380: { 1381: // Replace the target with the replacement 1382: result.replace(startPos, startPos + targetLength, replaceString); 1383: 1384: // Search for a new occurrence of the target 1385: startPos = result.indexOf(targetString, startPos + replaceLength); 1386: } 1387: return result.toString(); 1388: } 1389: 1390: 1391: private native void init(char[] chars, int offset, int count, 1392: boolean dont_copy); 1393: private native void init(byte[] chars, int hibyte, int offset, int count); 1394: private native void init(byte[] chars, int offset, int count, String enc) 1395: throws UnsupportedEncodingException; 1396: private native void init(gnu.gcj.runtime.StringBuffer buffer); 1397: }