Pergunta

Por que é java.lang.String a única classe para a qual duas maneiras de existir criação:

1) Com forma normal com palavra-chave "new".

String s = new String("abc");

2) Com literal String (que só está disponível com classe String)

String s = "abc";

Então, por que existem literais String e não literais para quaisquer outras classes ??

Foi útil?

Solução

String, sendo uma classe comum, representa um dos elementos básicos da programação (sendo os outros números e valores booleanos). Portanto, Java considerou objetos String como variáveis ??semi-primitivas de um dia, e permitiu isso.

Mais tarde, quando auto-boxing tornou-se parte do compilador padrão, você também pode construir objetos do wrapper numéricos, desta forma, i.

Integer i = 123;

como Tom Hawtin-tackline menciona nos comentários para a questão.

Outras dicas

A resposta mais curta, porque os projetistas da linguagem senti-lo.

Eu acho que String é uma classe tão comum que eles fizeram uma exceção. Eu tenho certeza que há algumas outras exceções semelhantes, bem como, (ver Tom Hawtins comentário)

Deixando de lado autoboxing (que não conta IMO - os literais são para os tipos primitivos em vez das classes; há apenas uma conversão implícita à classe wrapper), o construtor String(String) é realmente útil. É preciso uma cópia dos dados de caracteres, o que significa que, se o ORIGINAL string é pequeno, mas com uma grande char[] apoio, a nova cadeia é independente do mesmo.

Isso pode ser importante se você estiver lendo linhas curtas de um arquivo, por exemplo.

Quanto à razão existem strings literais: porque eles são úteis. O que você tem em vez disso? Será que você quer forçar os desenvolvedores a usar:

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

e ao mesmo tempo não se internar?

O que outra classe que você quer um literal para? Indiscutivelmente literais para mapas e listas seria útil - Eu não me lembro se eles estão vindo em Java 7 ou não. Você pode pensar em inicializadores de matriz como "um pouco como um literal" na medida em que é um atalho para a inicialização do objeto.

Eu suponho porque String é como o tipo de dados fundamental que eles consideram-no mesmo nível como primitivos.

Btw,

new String("abc");

realmente cria 2 Cordas:

  1. o internados, dos quais você perde a referência
  2. uma nova instância com o mesmo conteúdo

Pessoalmente, eu nunca encontrar uma necessidade de usar o construtor de cadeia.

Os tipos de objetos que têm literais são cordas , nulo literais classe .

Também é possível usar initialisers para matrizes e literais primitivos também pode ser usado para criar objetos se usado como initialisers, que se encaixam as "duas formas de criação" na sintaxe simples sem ser verdadeiros literais (eles só podem ser usados ??para inicializar um valor e não em todos os lugares que um objeto expressão pode ocorrer).

Se você usar outras técnicas, como a serialização e reflexão, você pode quebrar as "duas formas de criação" também.

Java 7 está previsto para fornecer a capacidade de coleções iniciais via literais muito parecido com os literais de matriz:

Última vez que verifiquei:

Integer wInt = 1;

funciona muito bem.

A última forma de criação também envolve Cordas Internar. Ou seja, se você tem o código:

String s = "abc";
String t = "abc";

o compilador irá otimizar isso e você tem duas referências para o mesmo objeto String. (S == t será verdade).

Cordas internar obras para expressões de cadeia também.

Existem, é claro, também literais para todos os tipos numéricos primitivos, e os booleans verdadeiros e falsos, e chars. Eu suponho que você poderia responder que na sua pergunta você disse tecnicamente "não literais para qualquer outra aulas ". OK. Eu acho que alguém apontou que "nulo" é um objeto literal, assim que sua afirmação é tecnicamente impreciso, mas eu acho que é o único outro exemplo.

Mas, em seguida, a próxima pergunta óbvia é, que outras aulas que você iria querer ter literais para? Se você estivesse projetando a língua, o que seria um olhar literal BufferedReader como? Ou um ResultSet literal? Ou um JCheckBox?

Você poderia, teoricamente, dizer que, por exemplo, um "literal File" é o nome do arquivo fechado em alguns delimitador especial, como "$ / home / bob / $ myfile.txt". Mas então alguém poderia dizer: Que tal um JButton, não poderíamos fazer uma literal para que, assim como com o texto do botão eo ActionListener ele é acionado e delimitadores apropriados, como "% Enviar, SubmitListener%". E então o que acontece com Sockets, não poderíamos colocar o nome do host em algum delimitador especial, etc. Eu acho que é bastante claro que iria rapidamente ficar sem sinais de pontuação para usar como delimitadores. Então nós acabam por ter de escrever algum tipo de texto para identificar qual a classe que estamos a falar, como dizer File ( "/ home / bob / myfile.txt") ou Socket ( "www.example.com", 631 ). Mas que parece um lote terrível como um construtor, e nós estaríamos de volta à direita para que os autores de Java realmente fez.

O número de "coisas" que podem ser expressos exclusivamente pela natureza do valor (por exemplo, todos os dígitos fazer um literal numérico) ou com pontuação é bastante limitada pelo número de marcas de pontuação que podem ser reaonably caber em um teclado. E você iria querer um teclado com 600 ícones especiais para todos os diferentes tipo de coisas que você pode querer falar? As palavras são muito mais fácil e mais flexível.

String é tão comumente usado, e as alternativas teria sido tão estranho, que fazia sentido para torná-lo um caso especial.

string literais são um atalho conveniente, com uma precedência bem estabelecida (em C) e sintaxe. Se os designers Java queria atrair programadores C ++ mais, as strings literais tinha que estar lá. Felizmente, a manipulação de strings é muito mais sã em Java do que em C ++.

Não há outros objetos padrão teve uma de facto sintaxe - como você escrever um mapa literal?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top