Notas de estudo de string e JVM

índice

Código fonte

 Parte de inicialização

 método

JVM

crio

Piscina constante

+ e anexar

Pergunta da entrevista 1: diferença de String, StringBuffer, StringBuilder

Pergunta da entrevista 2: String a = new String ("kexin"); Vários objetos são gerados


  • Código fonte

  •  Parte de inicialização

        Implementadas Serializable, Comparable, CharSequence três interfaces, ou seja, serialization, compareTo e CharSequence, a terceira herdou principalmente alguns métodos comuns, length, charAt, subSequence, etc., subSequence é semelhante a subString, o efeito é o mesmo, o tipo de valor de retorno é diferente , Basicamente, não use

     public final class String
     implements java.io.Serializable, Comparable<String>, CharSequence {
//     存储空间,字符数组形式
    private final char value[];
//    hashcode缓存,String常用于比较,每次计算太过麻烦,这样节省时间
    private int hash; 
//    序列号(尚未理解)
    private static final long serialVersionUID = -6849794470754667710L;
  •  método

cópia de 

//内部方法,将String的字符数组value整个复制到dst字符数组中,在dst数组的dstBegin位置开始拷贝
void getChars(char dst[], int dstBegin) {
        System.arraycopy(value, 0, dst, dstBegin, value.length);
    }


public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
        if (srcBegin < 0) {
            throw new StringIndexOutOfBoundsException(srcBegin);
        }
        if (srcEnd > value.length) {
            throw new StringIndexOutOfBoundsException(srcEnd);
        }
        if (srcBegin > srcEnd) {
            throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
        }
        System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
    }

Comparado

public boolean equals(Object anObject) {
//如果对象引用地址相同
        if (this == anObject) {
            return true;
        }
//这个是?存疑
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
//字符数组长度相同
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
//每个字符相同
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

Comparação (deixe a ser adicionado)

 public int compareTo(String anotherString) {
        int len1 = value.length;
        int len2 = anotherString.value.length;
        int lim = Math.min(len1, len2);
        char v1[] = value;
        char v2[] = anotherString.value;

        int k = 0;
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        return len1 - len2;
    }

Cortar

 public String substring(int beginIndex, int endIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        if (endIndex > value.length) {
            throw new StringIndexOutOfBoundsException(endIndex);
        }
        int subLen = endIndex - beginIndex;
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
//生成新对象
        return ((beginIndex == 0) && (endIndex == value.length)) ? this
                : new String(value, beginIndex, subLen);
    }

 Substituir (deixar para ser adicionado)

 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;
                }
            }
            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++;
                }
                return new String(buf, true);
            }
        }
        return this;
    }


Também pode ser visto a partir do código-fonte acima que quaisquer alterações no objeto String não afetarão o objeto original e quaisquer operações de alteração relacionadas irão gerar novos objetos.

  • JVM

  • crio

Há um conceito aqui, chamado Flyweight. Meu entendimento é compartilhar os elementos existentes no pool constante e reduzir o custo de memória
. Existem duas maneiras de criar:
1. String a = "a";
Ao criar, o jvm julgará primeiro Se "a" já existe no pool de constantes, se existir, será citado diretamente; se não existir, a string será instanciada e, em seguida, entre aspas.
Finalmente, o endereço de referência de "a" no pool de constantes de string é armazenado na pilha
2.String b = new String ("A");
Primeiro, um novo objeto de string é colocado no heap e o heap é armazenado no endereço de referência de pool constante "A", o endereço de referência de pool constante é obtido como acima.
Finalmente, a pilha é armazenada O endereço de referência do objeto string no heap.
Portanto, é impossível que duas strings idênticas existam no pool constante. Esta é uma manifestação da imutabilidade das strings.

 

  • Piscina constante


Existem dois tipos de pools de constantes, pool de constantes estáticas e pool de constantes de tempo de execução.
Compilar pool de constantes estáticas de tempo já colocado antes da constante de execução, como String a = "1"; String a1 = "1" + "2";
execute Conjunto de constante de tempo de execução gerado apenas em variáveis ​​de tempo de execução - como String b = new String ("1"); String b1 = "1" + b;
Nota:
(1): pares JVM String str = "abc" Os objetos são colocados no pool constante no tempo de compilação, e String str3 = str1 + str2 só pode ser conhecido em tempo de execução. O novo objeto também é feito em tempo de execução.
(2): A emenda literal "+" é realizada durante a compilação, e a string emendada é armazenada no pool de strings; e a operação de emenda "+" da referência de string é realmente realizada em tempo de execução, a string recém-criada Armazene em uma pilha.

O conjunto de constantes estáticas, no arquivo de classe, armazena as informações de string, classe e método, etc., que ocupam a maior parte do espaço de memória da classe.
Conjunto de constantes de tempo de execução. Depois que o jvm conclui a operação de carregamento de classe, ele colocará o conjunto de constantes de classe na área do método. , De modo geral, o pool constante se refere ao pool constante na área do método
 

JVM

estagiário

O método interno é um método nativo. O método interno consultará se a string atual existe no pool de constantes de string. Se existir, ele retornará diretamente a string atual; se não existir, colocará a string atual no pool de constantes e, em seguida, Retorna.

  • + e anexar


O + em String é interpretado como a criação de um objeto StringBuffer, chamando o método append (), chamando toString () e, finalmente, destruindo o objeto StringBuffer no processo de compilação,
como String A = "11" + "22" + Str1 + "33" ; Este processo é interpretado como String A = new StringBuffer ("1122"). Append (Str) .append ("33"). ToString () em tempo de compilação;
portanto, quando a operação + precisa ser realizada no loop, na verdade Irá consumir muito desempenho na criação e destruição de StringBuffer, é melhor criar manualmente um StringBuffer em vez de String

  • Pergunta da entrevista 1: diferença de String, StringBuffer, StringBuilder


Uma das perguntas mais frequentes em entrevistas
(1) pode ser imutável, String é modificada com final, estaticamente imutável e as outras duas são variáveis ​​em comprimento. É por isso que anexar às vezes é usado em vez de +. Anexar é expandido na base original e + é O
thread String (2) recém-criado é seguro? O string é imutável (pode ser entendido como uma constante) e não haverá conflitos causados ​​por vários threads alterando um recurso ao mesmo tempo, por isso é considerado seguro.
   StringBuffer usa synchronized para adicionar bloqueios de sincronização, thread safe, StringBuffer não existe, então não é seguro para thread
(3) Eficiência de execução, relativamente falando, StringBuilder> StringBuffer> String, análise específica da situação específica
(4) Cada recurso, uma pequena quantidade de dados String é flexível e mutável, uma grande quantidade de dados StringBuffer multiencadeado de segurança de thread, uma grande quantidade de dados StringBuilder de thread único é mais rápido

 

  • Pergunta da entrevista 2: String a = new String ("kexin"); Vários objetos são gerados


No estágio de carregamento da classe, um objeto "kexin" é gerado e colocado no heap.
No estágio de execução, um objeto a
é gerado, então há dois


Porção dopada acima do entendimento pessoal, bem-vindo para discutir e me corrigir
Referências

https://blog.csdn.net/yulungggg/article/details/81039655

https://blog.csdn.net/qq_34490018/article/details/82110578

https://www.cnblogs.com/xiaoxi/p/6036701.html

 

Acho que você gosta

Origin blog.csdn.net/qq_36766417/article/details/107936176
Recomendado
Clasificación