Como uma string pode ser inicializada usando ""?


154

Se String é uma classe como qualquer outra, como pode ser inicializada usando aspas duplas?


25
String é uma classe VIP. " "já é uma String!
— precisa saber é o seguinte

2
Nenhum significado especial. Eu só quis dizer muito importante. Ou seja, java.lang.Stringtenha um tratamento especial da linguagem Java.
— precisa saber é o seguinte

16
Quem disse que essa string é "uma classe como qualquer outra"? É uma classe muito especial, diferente de qualquer outra. Como sua suposição é falsa, a pergunta não é realmente responsável.
— Eric Lippert

5
Só porque a suposição é falsa, não significa que a pergunta não seja respondida. E a resposta correta já tem 197 votos.
— Koray Tugay

Respostas:


293

Java String é especial

Os designers de Java decidiram manter os tipos primitivos em uma linguagem orientada a objetos, em vez de transformar tudo em um objeto, a fim de melhorar o desempenho da linguagem. As primitivas são armazenadas na pilha de chamadas, que exigem menos espaços de armazenamento e são mais baratas de manipular. Por outro lado, os objetos são armazenados no heap do programa, o que requer gerenciamento de memória complexo e mais espaços de armazenamento.

Por motivos de desempenho, a String do Java foi projetada para ficar entre uma primitiva e uma classe.

Por exemplo

String s1 = "Hello";              // String literal
String s2 = "Hello";              // String literal
String s3 = s1;                   // same reference
String s4 = new String("Hello");  // String object
String s5 = new String("Hello");  // String object

insira a descrição da imagem aqui

Nota: Os literais de sequência são armazenados em um conjunto comum. Isso facilita o compartilhamento de armazenamento para seqüências de caracteres com o mesmo conteúdo para economizar armazenamento. Stringos objetos alocados por meio de um novo operador são armazenados no diretório heape não há compartilhamento de armazenamento para o mesmo conteúdo.


72
Observe que o "pool comum" geralmente faz parte do heap.
— Joachim Sauer

3
@JoachimSauer Sim ... com pequenos benefícios :) acrescentou isso na nota. Obrigado por lembrar.
— precisa

2
Então é mais rápido escrever String s1 = "Hello"; do que String s2 = new String ("Hello") ;?
— user2097804

28
Eu gostaria de acrescentar que no seu exemplo s1 == s2 == s3 mas s4 = S5!
— Alfredo Osorio

8
@AndrewJanke em recente jvm hotspot (7), o conjunto de cadeia não está na perm gen e de Java 8 não há perm gen nenhum mais ...
— assylias

50

Java trata String como uma classe especial, você pode inicializar dos dois modos

  1. Atribuindo literalmente literalmente

    String a = "adsasdf";
  2. Como outros objetos usando a nova palavra-chave

    String a = new String("adsasdf");

Você precisa tomar um cuidado especial quando quiser comparar com o ==sinal:

String a = "asdf";
String b = "asdf";
System.out.println(a == b);  // True
System.out.println(a.equals(b)); // True

String a = new String("asdf");
String b = new String("asdf");
System.out.println(a == b);  // False
System.out.println(a.equals(b)); // True

Isso ocorre porque, no primeiro caso, os objetos a e b são mantidos em algo chamado literal poole ambos referenciam o mesmo objeto para que sejam iguais nos dois sentidos.

Mas, no segundo caso, aeb faz referência a objetos diferentes, como quando inicializamos outros objetos. portanto, são desiguais quando comparados com o ==operador, enquanto são iguais em valores.


18

String recebe tratamento especial no JLS: é um dos dois tipos não primitivos para os quais literais existem (o outro é Class) * .

Do JLS :

Um literal de string é uma referência a uma instância da classe `String [...].

* bem, há também o "tipo nulo" com seu "literal nulo" null, mas a maioria das pessoas não pensa no "tipo nulo" como um tipo adequado.


1
Também não sabia que "tipo nulo" é um tipo adequado em Java. Suas informações muito úteis, você deve aumentar o tamanho da fonte.
— Grijesh Chauhan

1
@GrijeshChauhan: bem, o "tipo nulo" é apenas um texto bacana para permitir que qualquer um nullseja atribuído a qualquer variável do tipo de referência. Caso contrário, não é um tipo interessante.
— Joachim Sauer

15

É um recurso da linguagem Java. Literais de string no código fonte recebem tratamento especial.

A especificação da linguagem, aqui , simplesmente diz que uma string literal é do Stringtipo


5

O texto entre aspas duplas cria um Stringobjeto literal .

String myString = "Some text";

O código acima cria um Stringobjeto, usando aspas duplas.


4

Strings são frequentemente usadas em uma linguagem de programação. Como java é orientado a objetos, uma string é um objeto. Para evitar a nova e complicada String ("someString"); Sempre que você precisar de um objeto string, o java permite que você crie um objeto string usando o literal string.

Mas você deve ter em mente a igualdade das cordas. Aqui está um pequeno teste JUnit para demonstrar o que quero dizer.

    @Test
    public void stringTest() {
       // a string literal and a string object created 
       // with the same literal are equal
       assertEquals("string", new String("string"));

       // two string literals are the same string object
       assertSame("string", "string"); 

       // a string literal is not the same object instance 
       // as a string object created with the same string literal
       assertFalse("string" == new String("string"));

       // java's String.intern() method gives you the same
       // string object reference for all strings that are equal.
       assertSame("string", new String("string").intern());
    }

Se você pudesse inicializar apenas uma sequência com new String(String src), não seria capaz de fornecer ao construtor uma sequência literal. Você precisaria inicializar um char []e, em seguida, usar o String(char [] src)consrutor para construir a string, ou teria que ler a string de um arquivo.
— precisa saber é o seguinte

Isso não é correto. Um literal de cadeia de caracteres é apenas uma sequência de caracteres em um arquivo de origem com aspas duplas. Java cria automaticamente uma instância de uma sequência usando esse literal. Portanto, um objeto literal e um String são iguais, mas não são os mesmos. O Java também pode ter sido implementado dessa maneira, você deve usar o novo String (""); instanciar um objeto String, mas isso só tornaria nossa vida mais difícil. Portanto, quando você escreve uma nova String ("uma string"), o java cria um objeto String para o literal "uma string" e passa esse objeto ao construtor da nova String.
— René Link

2

Apenas para mencionar. Um literal a string é uma referência a uma instância da classe String. Você pode escrever um código como este:

 "abc" .getBytes ();

 "a: b: c" .split (":");

 "愛" .codePointAt (0);

2

- String é uma classe em Java . Você está certo sobre isso, para que possamos sempre inicializar com a newpalavra - chave.

- Mas quando fazemos algo como:

String s = "";

A instrução acima é marcada pelo compilador como um objeto String especial e, em seguida, a JVM durante o carregamento da classe (o carregamento é feito antes da inicialização), vê isso conhecido como literal de cadeia , armazenado em um conjunto literal de cadeias .

- Assim, uma String pode ser criada usando new()e pelo ""método, mas o último fornece uma literal de string que permanece na pilha mesmo quando não há referência a esse objeto de string, porque ela tem uma referência do pool literal de strings.


2

Java faz um processo em duas etapas para nós.

String str = "hello";

é equivalente a

char data[] = {'h', 'e', 'l' , 'l', 'o'};
String str = new String(data);

Como se o [.NET] [1] tivesse algo parecido.

String(Char[]) constructor

faz

String(char[] value)

Adicionando referências: -


2
O processo que você descreve não é o que o Java realmente faz: Como outros já declararam, "hello"é uma cadeia de caracteres literal e será colocada no pool constante pelo compilador, consulte JLS §3.10.5 e JVMS §5.1 .
— siegi 10/07/2013

1

Java.lang.Stringnão é apenas uma classe. É parte integrante da linguagem principal. O compilador possui açúcar sintático para ele. Por exemplo, ""é como uma abreviação de new String(""). Quando gravado, ""o compilador otimiza seqüências idênticas para a mesma instância para economizar espaço."a" + 5 == "a5" ==> true

O compilador possui açúcar sintático para muitas coisas, incluindo não ter que caixa / unbox entre versões de objetos e seus tipos nativos, nenhum pai significa Objeto, construtor padrão, ...


5
""não é uma abreviação para new String(""). Se você usar "", a primeira coisa a ser feita é procurar correspondências no conjunto String da JVM e, se isso for verdade, ele retornará essa String. Ao usar new String(""), você sempre criará uma nova String, mesmo que a própria String já exista no pool de String (porque não será armazenada no pool de String).
— G00glen00b

Eu atualizei minha resposta. As pessoas usam isso para sua vantagem, como usar constantes de string como um equivalente ao tipo de símbolo Lisp?
— 21413 Sylwester
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.