Maison > Java > javaDidacticiel > Exemple d'interprétation du code source de String

Exemple d'interprétation du code source de String

零下一度
Libérer: 2017-06-29 09:55:32
original
1518 Les gens l'ont consulté

La classe String maintient en interne une valeur de type char[] pour stocker les chaînes. Le code source est relativement simple.

1. Immuabilité

L'immuabilité de String se reflète principalement sous trois aspects :

  • La classe String est définie comme un type final. . Ne ​​peut pas être hérité

  • La valeur[] dans String est définie comme finale

  • Toutes les opérations dans String qui génèrent une nouvelle String sont appelées à la fin. bottom Array.copy ou System.copy pour générer un nouvel objet String

2 Constructeur, le constructeur de String est relativement simple, mais les suivants sont plus spéciaux
    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }
    
    String(char[] value, boolean share) {
        // assert share : "unshared not supported";
        this.value = value;
    }
Copier après la connexion
Les deux ci-dessus sont un type spécial de constructeur. Le premier utilise une chaîne prête à l'emploi pour initialiser un nouvel objet String. La méthode constructeur pointe directement la valeur du nouvel objet String vers l'ancien objet valeur. Puisque String est immuable, il n’est pas nécessaire de recopier l’objet valeur ici. Le deuxième constructeur semble détruire l'immuabilité du type String (String changera également lorsque la valeur du paramètre change), mais ce constructeur n'est pas déclaré public et ne peut être utilisé que dans le package String() déclaré public. char value[]) La couche inférieure appelle Array.copy pour réaliser la copie des données sous-jacentes. Les deux constructeurs ci-dessus ne sont plus recommandés

    public String(char value[], int offset, int count) {
        if (offset < 0) {
            throw new StringIndexOutOfBoundsException(offset);
        }
        if (count < 0) {
            throw new StringIndexOutOfBoundsException(count);
        }
        // Note: offset or count might be near -1>>>1.
        if (offset > value.length - count) {
            throw new StringIndexOutOfBoundsException(offset + count);
        }
        this.value = Arrays.copyOfRange(value, offset, offset+count);
    }
Copier après la connexion
Le constructeur ci-dessus est plus typique et il existe de nombreux autres constructeurs. .Ils sont similaires ou le constructeur sous-jacent est appelé. Les paramètres d'entrée sont un tableau de caractères (byte[]), une position de décalage et un décalage de nombre. La couche inférieure appelle la fonction Arrays.copy pour effectuer une copie approfondie.

    public String(StringBuffer buffer) {
        synchronized(buffer) {  //保证线程安全
            this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
        }
    }
    
    public String(StringBuilder builder) {
        this.value = Arrays.copyOf(builder.getValue(), builder.length());
    }
Copier après la connexion
Les paramètres d'entrée des deux constructeurs ci-dessus sont respectivement StringBuffer et StringBuilder. La couche inférieure appelle Arrays.copyOf. La seule différence est que StringBuffer est thread-safe et que le mot clé synchronisé doit être utilisé dans. tous les appels.

3. Autres méthodes
    static int indexOf(char[] source, int sourceOffset, int sourceCount,
            char[] target, int targetOffset, int targetCount,
            int fromIndex) {
        if (fromIndex >= sourceCount) {
            return (targetCount == 0 ? sourceCount : -1);
        }
        if (fromIndex < 0) {
            fromIndex = 0;
        }
        if (targetCount == 0) {
            return fromIndex;
        }

        char first = target[targetOffset];
        int max = sourceOffset + (sourceCount - targetCount);

        for (int i = sourceOffset + fromIndex; i <= max; i++) {
            /* Look for first character. */
            if (source[i] != first) {
                while (++i <= max && source[i] != first);
            }

            /* Found first character, now look at the rest of v2 */
            if (i <= max) {
                int j = i + 1;
                int end = j + targetCount - 1;
                for (int k = targetOffset + 1; j < end && source[j]
                        == target[k]; j++, k++);

                if (j == end) {
                    /* Found whole string. */
                    return i - sourceOffset;
                }
            }
        }
        return -1;
    }
    
    static int lastIndexOf(char[] source, int sourceOffset, int sourceCount,
            char[] target, int targetOffset, int targetCount,
            int fromIndex) {
        /*
         * Check arguments; return immediately where possible. For
         * consistency, don&#39;t check for null str.
         */
        int rightIndex = sourceCount - targetCount;
        if (fromIndex < 0) {
            return -1;
        }
        if (fromIndex > rightIndex) {
            fromIndex = rightIndex;
        }
        /* Empty string always matches. */
        if (targetCount == 0) {
            return fromIndex;
        }

        int strLastIndex = targetOffset + targetCount - 1;
        char strLastChar = target[strLastIndex];
        int min = sourceOffset + targetCount - 1;
        int i = min + fromIndex;

        startSearchForLastChar:
        while (true) {
            while (i >= min && source[i] != strLastChar) {
                i--;
            }
            if (i < min) {
                return -1;
            }
            int j = i - 1;
            int start = j - (targetCount - 1);
            int k = strLastIndex - 1;

            while (j > start) {
                if (source[j--] != target[k--]) {
                    i--;
                    continue startSearchForLastChar;
                }
            }
            return start - sourceOffset + 1;
        }
    }
Copier après la connexion
indexOf et lastIndexOf sont principalement les appels sous-jacents des fonctions index et lastIndex En parcourant le code, vous constaterez que l'implémentation sous-jacente n'a pas de fonction. Algorithme kmp particulièrement génial, c'est toujours une analyse caractère par caractère qui est implémentée. Parmi eux, lastIndexOf utilise toujours continue startSearchForLastChar ;

    public String replace(char oldChar, char newChar) {
        if (oldChar != newChar) {
            int len = value.length;
            int i = -1;
            char[] val = value; /* avoid getfield opcode */

            while (++i < len) {
                if (val[i] == oldChar) {
                    break;
                }
            }
            //如果找不到则返回this
            if (i < len) {
                char buf[] = new char[len];
                for (int j = 0; j < i; j++) {
                    buf[j] = val[j];
                }
                while (i < len) {
                    char c = val[i]; //替换
                    buf[i] = (c == oldChar) ? newChar : c;
                    i++;
                }
                //返回新的String,利用上述包内的非public构造函数
                return new String(buf, true);
            }
        }
        return this;
    }
Copier après la connexion
replace est utilisé pour remplacer un caractère dans l'objet String par un autre caractère. Si le caractère spécifié est introuvable, il retournera lui-même. S'il est trouvé, un nouvel objet String sera créé et. est revenu.

---Fin du contenu de récupération---

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal