Como uma string pode ser inicializada usando ""?

154

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

splitgames
fonte
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.

Suresh Atta
fonte
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.

chetan
fonte
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.

Joachim Sauer
fonte
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

n
fonte
5

O texto entre aspas duplas cria um Stringobjeto literal .

String myString = "Some text";

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

tristan2468
fonte
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());
    }
René Link
fonte
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);
mkdev
fonte
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.

Kumar Vivek Mitra
fonte
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: -

user1769790
fonte
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, ...

Sylwester
fonte
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