String源码解析(二) – songoo

方法的主要功能看代码注释即可,这里主要看函数实现的方式。

1.getChars(char dst[], int dstBegin)

1     /**
2      * Copy characters from this string into dst starting at dstBegin.
3      * This method doesn't perform any range checking.
4      */
5     void getChars(char dst[], int dstBegin) {
6         System.arraycopy(value, 0, dst, dstBegin, value.length);
7     }

该方法将调用该方法的字符串拷贝到字符数组dst中,从dstBegin开始存放,拷贝length字节。

该方法默认是包范围的,而且不进行边界检查。

2.getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)

 1     /**
 2      * Copies characters from this string into the destination character
 3      * array.
 4      * <p>
 5      * The first character to be copied is at index {@code srcBegin};
 6      * the last character to be copied is at index {@code srcEnd-1}
 7      * (thus the total number of characters to be copied is
 8      * {@code srcEnd-srcBegin}). The characters are copied into the
 9      * subarray of {@code dst} starting at index {@code dstBegin}
10      * and ending at index:
11      * <blockquote><pre>
12      *     dstBegin + (srcEnd-srcBegin) - 1
13      * </pre></blockquote>
14      *
15      * @param      srcBegin   index of the first character in the string
16      *                        to copy.
17      * @param      srcEnd     index after the last character in the string
18      *                        to copy.
19      * @param      dst        the destination array.
20      * @param      dstBegin   the start offset in the destination array.
21      * @exception IndexOutOfBoundsException If any of the following
22      *            is true:
23      *            <ul><li>{@code srcBegin} is negative.
24      *            <li>{@code srcBegin} is greater than {@code srcEnd}
25      *            <li>{@code srcEnd} is greater than the length of this
26      *                string
27      *            <li>{@code dstBegin} is negative
28      *            <li>{@code dstBegin+(srcEnd-srcBegin)} is larger than
29      *                {@code dst.length}</ul>
30      */
31     public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
32         if (srcBegin < 0) {
33             throw new StringIndexOutOfBoundsException(srcBegin);
34         }
35         if (srcEnd > value.length) {
36             throw new StringIndexOutOfBoundsException(srcEnd);
37         }
38         if (srcBegin > srcEnd) {
39             throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
40         }
41         System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
42     }

该方法先对srcBegin、srcEnd进行了边界检查,然后调用System.arraycopy实现复制。

3.getBytes()

 1     /**
 2      * Encodes this {@code String} into a sequence of bytes using the named
 3      * charset, storing the result into a new byte array.
 4      *
 5      * <p> The behavior of this method when this string cannot be encoded in
 6      * the given charset is unspecified.  The {@link
 7      * java.nio.charset.CharsetEncoder} class should be used when more control
 8      * over the encoding process is required.
 9      *
10      * @param  charsetName
11      *         The name of a supported {@linkplain java.nio.charset.Charset
12      *         charset}
13      *
14      * @return  The resultant byte array
15      *
16      * @throws  UnsupportedEncodingException
17      *          If the named charset is not supported
18      *
19      * @since  JDK1.1
20      */
21     public byte[] getBytes(String charsetName)
22             throws UnsupportedEncodingException {
23         if (charsetName == null) throw new NullPointerException();
24         return StringCoding.encode(charsetName, value, 0, value.length);
25     }
26 
27     /**
28      * Encodes this {@code String} into a sequence of bytes using the given
29      * {@linkplain java.nio.charset.Charset charset}, storing the result into a
30      * new byte array.
31      *
32      * <p> This method always replaces malformed-input and unmappable-character
33      * sequences with this charset's default replacement byte array.  The
34      * {@link java.nio.charset.CharsetEncoder} class should be used when more
35      * control over the encoding process is required.
36      *
37      * @param  charset
38      *         The {@linkplain java.nio.charset.Charset} to be used to encode
39      *         the {@code String}
40      *
41      * @return  The resultant byte array
42      *
43      * @since  1.6
44      */
45     public byte[] getBytes(Charset charset) {
46         if (charset == null) throw new NullPointerException();
47         return StringCoding.encode(charset, value, 0, value.length);
48     }
49 
50     /**
51      * Encodes this {@code String} into a sequence of bytes using the
52      * platform's default charset, storing the result into a new byte array.
53      *
54      * <p> The behavior of this method when this string cannot be encoded in
55      * the default charset is unspecified.  The {@link
56      * java.nio.charset.CharsetEncoder} class should be used when more control
57      * over the encoding process is required.
58      *
59      * @return  The resultant byte array
60      *
61      * @since      JDK1.1
62      */
63     public byte[] getBytes() {
64         return StringCoding.encode(value, 0, value.length);
65     }

这个三个方法都是将String编码为byte序列存储到byte数组后返回,都是调用StringCode.encode方法实现。

方法的不同之处是字符集指定方式,分别是字符集名字、字符集和平台默认字符集。

4.equals(Object anObject)

 1     /**
 2      * Compares this string to the specified object.  The result is {@code
 3      * true} if and only if the argument is not {@code null} and is a {@code
 4      * String} object that represents the same sequence of characters as this
 5      * object.
 6      *
 7      * @param  anObject
 8      *         The object to compare this {@code String} against
 9      *
10      * @return  {@code true} if the given object represents a {@code String}
11      *          equivalent to this string, {@code false} otherwise
12      *
13      * @see  #compareTo(String)
14      * @see  #equalsIgnoreCase(String)
15      */
16     public boolean equals(Object anObject) {
17         if (this == anObject) {
18             return true;
19         }
20         if (anObject instanceof String) {
21             String anotherString = (String)anObject;
22             int n = value.length;
23             if (n == anotherString.value.length) {
24                 char v1[] = value;
25                 char v2[] = anotherString.value;
26                 int i = 0;
27                 while (n-- != 0) {
28                     if (v1[i] != v2[i])
29                         return false;
30                     i++;
31                 }
32                 return true;
33             }
34         }
35         return false;
36     }

此方法将字符串与指定的对象anObject比较。

从代码中我们可以看出:

  先使用==进行判断,这是对字节码进行判断,如果二者相同则返回true;

  然后再判断anObject是否是一个String的一个实例,这是继续向下比较的条件;

  如果anObject是一个String实例,则转换为String;

  接下来比较两个字符串的长度,如果长度相等,再将两个字符串转换为char数组,对比相应位置上的元素。

  只有类型、长度和元素都相等的情况下才返回true。

5.contentEquals(StringBuffer sb)

 1   /**
 2      * Compares this string to the specified {@code StringBuffer}.  The result
 3      * is {@code true} if and only if this {@code String} represents the same
 4      * sequence of characters as the specified {@code StringBuffer}. This method
 5      * synchronizes on the {@code StringBuffer}.
 6      *
 7      * @param  sb
 8      *         The {@code StringBuffer} to compare this {@code String} against
 9      *
10      * @return  {@code true} if this {@code String} represents the same
11      *          sequence of characters as the specified {@code StringBuffer},
12      *          {@code false} otherwise
13      *
14      * @since  1.4
15      */
16     public boolean contentEquals(StringBuffer sb) {
17         return contentEquals((CharSequence)sb);
18     }

该方法将字符串与一个StringBuffer对象进行比较,具体的比较操作是调用contentEquals()方法实现的。

6.contentEquals(CharSequence cs)

 1   /**
 2      * Compares this string to the specified {@code CharSequence}.  The
 3      * result is {@code true} if and only if this {@code String} represents the
 4      * same sequence of char values as the specified sequence. Note that if the
 5      * {@code CharSequence} is a {@code StringBuffer} then the method
 6      * synchronizes on it.
 7      *
 8      * @param  cs
 9      *         The sequence to compare this {@code String} against
10      *
11      * @return  {@code true} if this {@code String} represents the same
12      *          sequence of char values as the specified sequence, {@code
13      *          false} otherwise
14      *
15      * @since  1.5
16      */
17     public boolean contentEquals(CharSequence cs) {
18         // Argument is a StringBuffer, StringBuilder
19         if (cs instanceof AbstractStringBuilder) {
20             if (cs instanceof StringBuffer) {
21                 synchronized(cs) {
22                    return nonSyncContentEquals((AbstractStringBuilder)cs);
23                 }
24             } else {
25                 return nonSyncContentEquals((AbstractStringBuilder)cs);
26             }
27         }
28         // Argument is a String
29         if (cs instanceof String) {
30             return equals(cs);
31         }
32         // Argument is a generic CharSequence
33         char v1[] = value;
34         int n = v1.length;
35         if (n != cs.length()) {
36             return false;
37         }
38         for (int i = 0; i < n; i++) {
39             if (v1[i] != cs.charAt(i)) {
40                 return false;
41             }
42         }
43         return true;
44     }

该方法的参数是一个字符序列cs,只进行内容的比较:

  如果cs是AbstractStringBuilder实例但不是StringBuffer实例,直接调用方法nonSyncContentEquals()进行比较;

  如果cs是StringBuffer实例,也是调用方法nonSyncContentEquals()实现比较,但是需要synchronized同步;

  如果cs不是AbstractStringBuilder实例,但是一个String实例,调用方法equals()实现比较;

  如果cs只是一个普通的字符序列,比较序列长度和对应位置字符相等就可以了。

7.nonSyncContentEquals(AbstractStringBuilder sb)

 1 private boolean nonSyncContentEquals(AbstractStringBuilder sb) {
 2         char v1[] = value;
 3         char v2[] = sb.getValue();
 4         int n = v1.length;
 5         if (n != sb.length()) {
 6             return false;
 7         }
 8         for (int i = 0; i < n; i++) {
 9             if (v1[i] != v2[i]) {
10                 return false;
11             }
12         }
13         return true;
14     }

这是一个私有方法。

从方法名就可以看出这是一个非同步比较方法,参数是AbstractStringBuilder类型。

比较时,也只是从AbstractStringBuilder取出字符数组,然后和调用者的字符数组进行比较。 

 

综上,我们可以看到,不同的equals函数实现不同的判等方式,比如:

只进行存储内容的判断,而不比较类类型;

不但进行类型的判断,还要对存储内容进行判断;

 



You must enable javascript to see captcha here!

Copyright © All Rights Reserved · Green Hope Theme by Sivan & schiy · Proudly powered by WordPress

无觅相关文章插件,快速提升流量