Uma string é imutável; então, por que elas não são todas constantes?

8

O stringtipo é imutável.

Podemos usar a constpalavra-chave com stringslinguagem de alto nível, como .NET. Meu entendimento de 'const' significa constante (permanece o mesmo, não podemos alterar o valor).

São stringsnem sempre constant(IMO o termo constantnão deve ser aplicável no mesmo contexto se o tipo tem de ser recriado cada vez que isso significa para o tempo valores vida, era constante)?

Em linguagens de alto nível, especificamente .NET (embora eu também estivesse interessado em Java), isso ocorre devido ao gerenciamento / rastreamento geral de objetos da memória ou há outro motivo?

Dave
fonte
6
Qual linguagem de programação você usa? A resposta pode depender de detalhes específicos da implementação do idioma.
Viliam Búr 15/03/2013
Sua definição de "constante" é difícil de entender. Você quer dizer "uma vez criado, ele sempre existe"? Se sim, a resposta deve ser óbvia: você ficará sem memória.
parsifal
1
Se não é isso que você quer dizer, então você está confundindo objetos e as variáveis ​​que apontam para eles. Uma "constante" em Java (e eu assumo. Net também) é simplesmente uma variável que nunca pode ser alterada.
parsifal
1
@DaveRook Em Java, o finalmodificador em uma variável de string impede que a variável seja alterada para apontar para uma string diferente.
1
O que exatamente precisa ser constante , o que exatamente não pode ser modificado: os caracteres em um objeto de string específico ou um objeto em uma variável específica? São duas coisas diferentes. Em Java, as strings são imutáveis , o que significa que, quando você cria um objeto de string, não pode modificá-lo ... mas pode jogá-lo fora e colocar outro objeto na mesma variável. A cadeia constante ("Cadeia final estática" em Java) significa que você não pode sequer substituir o objeto na variável.
Viliam Búr 15/03/2013

Respostas:

22

Você está confundindo duas coisas diferentes:

  • Imutável significa que o conteúdo da memória do objeto não pode ser modificado. Quando você modifica um objeto imutável (por exemplo, a string), o conteúdo da memória desse objeto não é modificado. Em vez de:

    1. Um novo bloco de memória está alocado.
    2. O conteúdo do objeto que você (tentou) modificar é copiado para este novo bloco, com a parte que você deseja alterar é alterada nesse novo bloco.
    3. O ponteiro (isto é, a referência) é atribuído a este novo bloco.
  • Constante significa que a variável não pode ser modificada em tempo de compilação. Se um stringou integero conteúdo da variável (ou para o que ela aponta) não pode ser alterado ou atribuído em tempo de compilação.

rae1
fonte
Obrigado. Estou sendo muito literal, mas isso responde muito bem.
Dave
1
Se você não pode modificar a constante no tempo de compilação, quando a modifica?
parsifal
2
@parsifal Se for um, constvocê não pode modificá-lo. Você pode defini-lo para um valor inicial, mas não pode atribuir um valor diferente a ele em nenhum outro lugar, portanto, não pode modificá-lo.
rae1
@ rae1n: isso não é 100% correto. Constante significa que uma variável não pode ser modificada em tempo de execução . É uma propriedade da variável que contém uma string, enquanto a imutabilidade é uma propriedade do próprio objeto.
Doc Brown
@DocBrown Você está dizendo que pode modificar uma constante em tempo de compilação?
rae1
6

Como dizem os comentários, você está confundindo "constante" com "imutável", quando eles realmente significam duas coisas muito diferentes.

Uma constante é uma variável que não pode ser alterada. Dependendo do idioma e do compilador, é inteiramente possível que o código compilado substitua simplesmente todo uso dessa variável pelo valor atribuído a ela; nesse caso, nunca seria alocado um ponto na memória. Mesmo se o compilador não otimizar dessa maneira, ele ainda está alocado um ponto na memória no lançamento (desde que constimplica static) e permanece lá até a saída.

Um imutável é um valor na memória que não pode ser alterado (até que a memória seja recuperada). É atribuído um lugar na memória, conforme necessário, e pode (teoricamente) ser armazenado em várias variáveis. Atribuir a uma variável que está apontando para um valor imutável simplesmente cria um novo imutável e altera a variável para apontar para ela. O valor antigo permanece na memória até a coleta de lixo, o que pode ocorrer mesmo enquanto o programa está sendo executado.

Bobson
fonte
3
+1 para explicar o que a constante está realmente fazendo: alinhar o valor da sua variável em qualquer lugar em que ela for referenciada; que é um mecanismo importante de entender, pois tem efeitos ainda maiores do que o mencionado aqui.
Jimmy Hoffa
2

Strings não podem mudar. Ponteiros para seqüências de caracteres podem mudar. O código a seguir é válido:

String text = "Text";
text = text.substring(1);

O objeto "Texto" original ainda está lá, inalterado e imutável, exceto que nada está apontando para ele. Um mutável Stringpermitiria que você o fizesse text.substring(1)sem precisar atribuí-lo de volta à textvariável e alteraria o objeto original. Se você deseja que a variável text não seja alterada, é quando você a faz const. Existem casos de uso válidos para ambos.

Como observação lateral, este é um bom exemplo de conceito mais fácil de entender em C ++, porque objetos e ponteiros para objetos têm tipos diferentes.

Karl Bielefeldt
fonte
1

Acredito que você esteja confundindo variáveis ​​e objetos.

Uma variável é simplesmente uma referência a um objeto .

Enquanto seu programa está sendo executado, uma variável pode se referir a vários objetos . Atribuir algo à variável não altera o objeto. Se não houver variáveis ​​que façam referência a um objeto, ele se tornará lixo.

A Stringé considerado imutável (em Java, e eu também esperaria em .Net) porque não há como alterar o objeto .

Uma constante é simplesmente uma variável que não pode ser alterada durante a vida útil do programa. Você define uma constante com o finalmodificador em Java e o constmodificador em .Net.

No entanto, se sua variável "constante" aponta para um objeto mutável, a "constância" da variável não afeta a mutabilidade do objeto (na verdade, não posso dizer isso com certeza no .Net, porque estou assumindo que herda algumas das regras misteriosas do C ++).

parsifal
fonte
@Downvoter - você gostaria de comentar? Ou devo assumir que você também não sabe a diferença entre uma variável e um objeto?
parsifal
1
Eu não sou o derrotador - mas você considera que nem todo mundo é Java ou C #?
Ingo
1
@Igno - bem, exceto que o OP disse "especificamente .NET (embora eu estivesse interessado em Java", limitando meus comentários aos dois. Dito isso, a separação entre variável e objeto também se aplica a JavaScript, Ruby, Python , Perl e PHP.De fato, além do C ++, não consigo pensar em outra linguagem moderna que afirme ser orientada a objetos que não faça essa distinção.
parsifal
-1

Uma demonstração simples do que é constadequado. Isso é aplicável ao C # e a idiomas semelhantes.

string noconst = "foo";
noconst = "bar"; //noconst has changed! It was declared as "foo" but now is "bar"

const string yesconst = "foo";
yesconst = "bar"; //compiler error
Brian
fonte
1
Enquanto isso demonstra como constse comporta, o comportamento não é exclusivo const. Em Java, a finalpalavra - chave se comporta de maneira semelhante e em C # a readonlypalavra - chave faz o mesmo. O único aspecto de a consté que ele é conhecido em tempo de compilação.
Corbin março