【シロのjava成長シリーズ】——String類の深い分析(ソースコードに基づく)


次に前を向いて話しましょう~今日はString類です.実はStringクラスにもオブジェクト向けの知識がたくさん含まれています~
まず質問です.私たちは開発の過程で、クラスを1つ使うなら、オブジェクトを作成しなければなりません.この言葉は大丈夫でしょう.実際に開発するときは確かにそうです.オブジェクトを作成してこそ、普通のクラスを本当に使用することができます.私たちは一般的にオブジェクトを作成します.ほとんどのクラスの作成オブジェクトはnewキーワードで作成されます.
問題が来た.のなぜ私たちのStringはString str=「abc」と直接書くことができますか.これは?
もちろんStringクラスはnewでオブジェクトを作成することもできます.の
実は難しくありません.ソースの説明を見て知っています.
 * Strings are constant; their values cannot be changed after they
 * are created. String buffers support mutable strings.
 * Because String objects are immutable they can be shared. For example:
 * <p><blockquote><pre>
 *     String str = "abc";
 * </pre></blockquote><p>
 * is equivalent to:
 * <p><blockquote><pre>
 *     char data[] = {'a', 'b', 'c'};
 *     String str = new String(data);
 * </pre></blockquote><p>

Stringのソースコードに入ると、一番前に上の文字が見えます.大体、Stringのオブジェクト値はchar[]配列で格納されています.String str=「abc」です.char data[]={'a','b','c'}に等しい.  String str = new String(data);分かったでしょ~
1、Stringクラスの定義:
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence 

質問:開発中、Stringクラスを継承できますか?
答え:だめです.定義を見ればわかりますが、Stringの定義はfinal修飾子を使用しており、クラスを終了するために定義されているので、Stringは拡張できません.
implements:このキーワードはインタフェースの役割を実現するために使用され、Serializable、Comparable、CharSequenceがインタフェースであることを意味します.
インタフェースのソースを表示するには、次の手順に従います.
Comparable  :コンパレータの役割を表し、java汎用形式を採用
Serializable:
public interface Serializable {
}

Serializableインタフェースには何もないのが見えますが、なぜこのインタフェースを実現するのでしょうか.このインタフェースの役割は何ですか?
役割:javaクラスのシーケンス化、シーケンス化については後述します.実はSerializableはjavaのタグインタフェースで、タグインタフェースとは何ですか?Serializableはただ1つのタグの作用として、その具体的な機能と作用についてJVMの底層に任せて実現して、このインタフェースを実現して、ただJVMに通知して、Stringのこのクラスはシーケンス化することができます.
CharSequence:文字シーケンスを表しましょう~これは何も言うことはありませんが、Stringの格納方式は文字シーケンスに依存します~
2、属性
    private final char value[];	//String      value[]  

    private int hash; // Default to 0    hash ,


    private static final long serialVersionUID = -6849794470754667710L;//     

    private static final ObjectStreamField[] serialPersistentFields =
            new ObjectStreamField[0];//     

Stringクラスの属性を知っていれば、ほとんど使いません.privateと定義されているので、私有化されています.3、構造方法
ここでもいくつかの特殊なことを言うだけで、一般的に開発の過程で構造方法を使うことはありません.newを使ってStringオブジェクトを作成することはめったにありません.String str=「abc」を直接使うからです.こんな形.
面接の過程で、多くの面接官がString str=new String(「abc」)を聞く.これはいくつのオブジェクトを作成しますか?答えや解釈については、こちらでは紹介しません.知りたいことはネットで調べてみましょう.この最下層のメモリの問題については、説明すると長編になります.
    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }
上から見ると、Stringの2つのコアはvalueとhashであり、この2つの値は基本的にStringオブジェクトを決定します.
    public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);
    }
これは下位配列コピーによって作成され、実際には
下位層はSystem.arrayCopy()という方法を用い,native修飾を用い,下位層はC/C++で実現されるが,実はコピーの役割である.
public String(byte bytes[], int offset, int length) {
        checkBounds(bytes, offset, length);
        this.value = StringCoding.decode(bytes, offset, length);
    }
この表現はバイト(byte)によって文字列を構築しているが,実際には下位層の実装もSystem.arrayCopy()という方法によって行われている.
他の基本も何も言うことはありませんが、理解すればいいです.@Deprecated注記を使用した構造を見ることができます.この注記は時代遅れで、この方法を推奨しません.
4、常用方法
    public int length() {	//       
        return value.length;
    }

	public boolean isEmpty() {//          
        return value.length == 0;
    }

	public char charAt(int index) {//         ,index       
        if ((index < 0) || (index >= value.length)) {
            throw new StringIndexOutOfBoundsException(index);
        }
        return value[index];
    }

	public byte[] getBytes() {//      
        return StringCoding.encode(value, 0, value.length);
    }

	public boolean equals(Object anObject) {//     ,               ==     ,
						//                 

主に==とequalsメソッドを検証します
package me.javen.oop;

public class StringDemo {

	public static void main(String[] args) {
		String str1 = "hello" ;					//     
		String str2 = new String("hello") ;		//   new  
		String str3 = str2 ;					//     
		System.out.println("str1 == str2 --> " + (str1==str2)) ;	// false
		System.out.println("str1 == str3 --> " + (str1==str3)) ;	// false
		System.out.println("str2 == str3 --> " + (str2==str3)) ;	// true
		
		//    equals  
		System.out.println("str1 equals str2 --> " + (str1.equals(str2))) ;	// true
		System.out.println("str1 equals str3 --> " + (str1.equals(str3))) ;	// true
		System.out.println("str2 equals str3 --> " + (str2.equals(str3))) ;	// true
	}

}
また、比較方法も多く使用されています.
public boolean equalsIgnoreCase(String anotherString) {//       
	public boolean startsWith(String prefix) {//         prefix  
	public boolean endsWith(String suffix) {//         suffix  
	public int hashCode() {//      hash 
	public int indexOf(String str) {//    str     ,-1        
        return indexOf(str, 0);
    }

	public String substring(int beginIndex, int endIndex) {//     beginIndex      ,endIndex      
	public String replaceAll(String regex, String replacement) {//     replacement  regex

	public String[] split(String regex) {//     ,regex     

	public String toLowerCase() {//           
	public String toUpperCase() {//           
	
	public String trim() {//      ,           

	public static String valueOf(Object obj) {// obj      ,          ,    ,  ,     

他にもいろいろな方法がありますが、ここでは挙げません.学習者はこれらの方法をコードで使用して、開発でよく使われる方法を列挙することができます.