string.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 1,585 行 · 第 1/4 页
JAVA
1,585 行
/* String.java -- immutable character sequences; the object of string literals
Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.lang;
import gnu.java.io.EncodingManager;
import gnu.java.lang.CharData;
import java.io.CharConversionException;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.Comparator;
import java.util.Locale;
import java.util.WeakHashMap;
import java.util.regex.Pattern;
import java.lang.ref.WeakReference;
/**
* Strings represent an immutable set of characters. All String literals
* are instances of this class, and two string literals with the same contents
* refer to the same String object.
*
* <p>This class also includes a number of methods for manipulating the
* contents of strings (of course, creating a new object if there are any
* changes, as String is immutable). Case mapping relies on Unicode 3.0.0
* standards, where some character sequences have a different number of
* characters in the uppercase version than the lower case.
*
* <p>Strings are special, in that they are the only object with an overloaded
* operator. When you use '+' with at least one String argument, both
* arguments have String conversion performed on them, and another String (not
* guaranteed to be unique) results.
*
* <p>String is special-cased when doing data serialization - rather than
* listing the fields of this class, a String object is converted to a string
* literal in the object stream.
*
* @author Paul N. Fisher
* @author Eric Blake <ebb9@email.byu.edu>
* @since 1.0
* @status updated to 1.4; but could use better data sharing via offset field
*/
public final class String implements Serializable, Comparable, CharSequence {
// WARNING: String is a CORE class in the bootstrap cycle. See the comments
// in vm/reference/java/lang/Runtime for implications of this fact.
/**
* This is probably not necessary because this class is special cased already
* but it will avoid showing up as a discrepancy when comparing SUIDs.
*/
private static final long serialVersionUID = -6849794470754667710L;
/**
* Holds the references for each intern()'d String. If all references to
* the string disappear, and the VM properly supports weak references,
* the String will be GC'd.
*/
private static WeakHashMap internTable;
/**
* Stores unicode multi-character uppercase expansion table.
* @see #toUpperCase(char)
* @see CharData#UPPER_EXPAND
*/
private static char[] hiddenUpperExpand;
private static char[] getUpperExpand() {
if (hiddenUpperExpand == null) {
hiddenUpperExpand = zeroBasedStringValue(CharData.UPPER_EXPAND);
}
return hiddenUpperExpand;
}
/**
* Stores unicode multi-character uppercase special casing table.
* @see #upperCaseExpansion(char)
* @see CharData#UPPER_SPECIAL
*/
private static char[] hiddenUpperSpecial;
private static char[] getUpperSpecial() {
if (hiddenUpperSpecial == null) {
hiddenUpperSpecial = zeroBasedStringValue(CharData.UPPER_SPECIAL);
}
return hiddenUpperSpecial;
}
/**
* Characters which make up the String.
* Package access is granted for use by StringBuffer.
*/
final char[] value;
/**
* Holds the number of characters in value. This number is generally
* the same as value.length, but can be smaller because substrings and
* StringBuffers can share arrays. Package visible for use by trusted code.
*/
final int count;
/**
* Caches the result of hashCode(). If this value is zero, the hashcode
* is considered uncached (even if 0 is the correct hash value).
*/
private int cachedHashCode;
/**
* Holds the starting position for characters in str[]. Since
* substring()'s are common, the use of offset allows the operation
* to perform in O(1). Package access is granted for use by StringBuffer.
*/
final int offset;
/**
* An implementation for {@link CASE_INSENSITIVE_ORDER}.
* This must be {@link Serializable}. The class name is dictated by
* compatibility with Sun's JDK.
*/
private static final class CaseInsensitiveComparator implements Comparator, Serializable {
/**
* Compatible with JDK 1.2.
*/
private static final long serialVersionUID = 8575799808933029326L;
/**
* The default private constructor generates unnecessary overhead.
*/
CaseInsensitiveComparator() {
}
/**
* Compares to Strings, using
* <code>String.compareToIgnoreCase(String)</code>.
*
* @param o1 the first string
* @param o2 the second string
* @return < 0, 0, or > 0 depending on the case-insensitive
* comparison of the two strings.
* @throws NullPointerException if either argument is null
* @throws ClassCastException if either argument is not a String
* @see #compareToIgnoreCase(String)
*/
public int compare(Object o1, Object o2) {
return ((String) o1).compareToIgnoreCase((String) o2);
}
} // class CaseInsensitiveComparator
/**
* A Comparator that uses <code>String.compareToIgnoreCase(String)</code>.
* This comparator is {@link Serializable}. Note that it ignores Locale,
* for that, you want a Collator.
*
* @see Collator#compare(String, String)
* @since 1.2
*/
public static final Comparator CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator();
/**
* Creates an empty String (length 0). Unless you really need a new object,
* consider using <code>""</code> instead.
*/
public String() {
value = "".value;
offset = 0;
count = 0;
}
/**
* Copies the contents of a String to a new String. Since Strings are
* immutable, only a shallow copy is performed.
*
* @param str String to copy
* @throws NullPointerException if value is null
*/
public String(String str) {
value = str.value;
offset = str.offset;
count = str.count;
cachedHashCode = str.cachedHashCode;
}
/**
* Creates a new String using the character sequence of the char array.
* Subsequent changes to data do not affect the String.
*
* @param data char array to copy
* @throws NullPointerException if data is null
*/
public String(char[] data) {
this(data, 0, data.length, false);
}
/**
* Creates a new String using the character sequence of a subarray of
* characters. The string starts at offset, and copies count chars.
* Subsequent changes to data do not affect the String.
*
* @param data char array to copy
* @param offset position (base 0) to start copying out of data
* @param count the number of characters from data to copy
* @throws NullPointerException if data is null
* @throws IndexOutOfBoundsException if (offset < 0 || count < 0
* || offset + count > data.length)
* (while unspecified, this is a StringIndexOutOfBoundsException)
*/
public String(char[] data, int offset, int count) {
this(data, offset, count, false);
}
/**
* Creates a new String using an 8-bit array of integer values, starting at
* an offset, and copying up to the count. Each character c, using
* corresponding byte b, is created in the new String as if by performing:
*
* <pre>
* c = (char) (((hibyte & 0xff) << 8) | (b & 0xff))
* </pre>
*
* @param ascii array of integer values
* @param hibyte top byte of each Unicode character
* @param offset position (base 0) to start copying out of ascii
* @param count the number of characters from ascii to copy
* @throws NullPointerException if ascii is null
* @throws IndexOutOfBoundsException if (offset < 0 || count < 0
* || offset + count > ascii.length)
* (while unspecified, this is a StringIndexOutOfBoundsException)
* @see #String(byte[])
* @see #String(byte[], String)
* @see #String(byte[], int, int)
* @see #String(byte[], int, int, String)
* @deprecated use {@link #String(byte[], int, int, String)} to perform
* correct encoding
*/
public String(byte[] ascii, int hibyte, int offset, int count) {
if (offset < 0 || count < 0 || offset + count > ascii.length)
throw new StringIndexOutOfBoundsException();
value = new char[count];
this.offset = 0;
this.count = count;
hibyte <<= 8;
offset += count;
while (--count >= 0)
value[count] = (char) (hibyte | (ascii[--offset] & 0xff));
}
/**
* Creates a new String using an 8-bit array of integer values. Each
* character c, using corresponding byte b, is created in the new String
* as if by performing:
*
* <pre>
* c = (char) (((hibyte & 0xff) << 8) | (b & 0xff))
* </pre>
*
* @param ascii array of integer values
* @param hibyte top byte of each Unicode character
* @throws NullPointerException if ascii is null
* @see #String(byte[])
* @see #String(byte[], String)
* @see #String(byte[], int, int)
* @see #String(byte[], int, int, String)
* @see #String(byte[], int, int, int)
* @deprecated use {@link #String(byte[], String)} to perform
* correct encoding
*/
public String(byte[] ascii, int hibyte) {
this(ascii, hibyte, 0, ascii.length);
}
/**
* Creates a new String using the portion of the byte array starting at the
* offset and ending at offset + count. Uses the specified encoding type
* to decode the byte array, so the resulting string may be longer or
* shorter than the byte array. For more decoding control, use
* {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
* see {@link java.nio.charset.Charset}. The behavior is not specified if
* the decoder encounters invalid characters; this implementation throws
* an Error.
*
* @param data byte array to copy
* @param offset the offset to start at
* @param count the number of characters in the array to use
* @param encoding the name of the encoding to use
* @throws NullPointerException if data or encoding is null
* @throws IndexOutOfBoundsException if offset or count is incorrect
* (while unspecified, this is a StringIndexOutOfBoundsException)
* @throws UnsupportedEncodingException if encoding is not found
* @throws Error if the decoding fails
* @since 1.1
*/
public String(byte[] data, int offset, int count, String encoding) throws UnsupportedEncodingException {
if (offset < 0 || count < 0 || offset + count > data.length)
throw new StringIndexOutOfBoundsException();
try {
// XXX Consider using java.nio here.
value = EncodingManager.getDecoder(encoding).convertToChars(data, offset, count);
} catch (CharConversionException cce) {
throw new Error(cce);
}
this.offset = 0;
this.count = value.length;
}
/**
* Creates a new String using the byte array. Uses the specified encoding
* type to decode the byte array, so the resulting string may be longer or
* shorter than the byte array. For more decoding control, use
* {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
* see {@link java.nio.charset.Charset}. The behavior is not specified if
* the decoder encounters invalid characters; this implementation throws
* an Error.
*
* @param data byte array to copy
* @param encoding the name of the encoding to use
* @throws NullPointerException if data or encoding is null
* @throws UnsupportedEncodingException if encoding is not found
* @throws Error if the decoding fails
* @see #String(byte[], int, int, String)
* @since 1.1
*/
public String(byte[] data, String encoding) throws UnsupportedEncodingException {
this(data, 0, data.length, encoding);
}
/**
* Creates a new String using the portion of the byte array starting at the
* offset and ending at offset + count. Uses the encoding of the platform's
* default charset, so the resulting string may be longer or shorter than
* the byte array. For more decoding control, use
* {@link java.nio.charset.CharsetDecoder}. The behavior is not specified
* if the decoder encounters invalid characters; this implementation throws
* an Error.
*
* @param data byte array to copy
* @param offset the offset to start at
* @param count the number of characters in the array to use
* @throws NullPointerException if data is null
* @throws IndexOutOfBoundsException if offset or count is incorrect
* @throws Error if the decoding fails
* @see #String(byte[], int, int, String)
* @since 1.1
*/
public String(byte[] data, int offset, int count) {
if (offset < 0 || count < 0 || offset + count > data.length)
throw new StringIndexOutOfBoundsException();
try {
// XXX Consider using java.nio here.
value = EncodingManager.getDecoder().convertToChars(data, offset, count);
} catch (CharConversionException cce) {
throw new Error(cce);
}
this.offset = 0;
this.count = value.length;
}
/**
* Creates a new String using the byte array. Uses the encoding of the
* platform's default charset, so the resulting string may be longer or
* shorter than the byte array. For more decoding control, use
* {@link java.nio.charset.CharsetDecoder}. The behavior is not specified
* if the decoder encounters invalid characters; this implementation throws
* an Error.
*
* @param data byte array to copy
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?