Estou acostumado a fazer o seguinte em C
:
void main() {
String zText = "";
fillString(zText);
printf(zText);
}
void fillString(String zText) {
zText += "foo";
}
E a saída é:
foo
No entanto, em Java, isso não parece funcionar. Presumo que o String
objeto seja copiado em vez de passado por referenciado . Eu pensei que Strings eram objetos, que são sempre passados por referência.
O que está acontecendo aqui?
java
string
pass-by-reference
Soren Johnson
fonte
fonte
Respostas:
Você tem três opções:
Use um StringBuilder:
Crie uma classe de contêiner e passe uma instância do contêiner para o seu método:
Crie uma matriz:
Do ponto de vista do desempenho, o StringBuilder é geralmente a melhor opção.
fonte
StringBuilder
é mais rápido que,s += "..."
uma vez que não aloca novos objetos String sempre. De fato, quando você escreve código Javas = "Hello " + name
, o compilador gera um código de bytes que cria aStringBuilder
e chamaappend()
duas vezes.Em Java, nada é passado por referência . Tudo é passado por valor . Referências a objetos são passadas por valor. Além disso, as seqüências de caracteres são imutáveis . Então, quando você anexa à String passada, obtém uma nova String. Você pode usar um valor de retorno ou passar um StringBuffer.
fonte
O que está acontecendo é que a referência é passada por valor, ou seja, uma cópia da referência é passada. Nada no java é passado por referência e, como uma sequência é imutável, essa atribuição cria um novo objeto de sequência para o qual a cópia da referência agora aponta. A referência original ainda aponta para a cadeia vazia.
Isso seria o mesmo para qualquer objeto, ou seja, defini-lo com um novo valor em um método. O exemplo abaixo apenas torna o que está acontecendo mais óbvio, mas concatenar uma string é realmente a mesma coisa.
fonte
java.lang.String é imutável.
Eu odeio colar URLs, mas https://docs.oracle.com/javase/10/docs/api/java/lang/String.html é essencial para você ler e entender se estiver em Java.
fonte
objetos são passados por referência, primitivos são passados por valor.
String não é um primitivo, é um objeto e é um caso especial de objeto.
Isso é para fins de economia de memória. Na JVM, há um conjunto de cadeias. Para cada sequência criada, a JVM tentará verificar se a mesma sequência existe no conjunto de sequências e apontará para ela se já houver uma.
/* RESULTADO */
o == está verificando o endereço da memória (referência) e o .equals está verificando o conteúdo (valor)
fonte
Todos os argumentos em Java são passados por valor. Quando você passa a
String
para uma função, o valor passado é uma referência a um objeto String, mas você não pode modificar essa referência, e o objeto String subjacente é imutável.A atribuição
é equivalente a:
Ou seja, (localmente) reatribui o parâmetro
zText
como uma nova referência, que aponta para um novo local de memória, no qual é um novoString
que contém o conteúdo originalzText
com"foo"
anexado.O objeto original não é modificado e a
main()
variável local do métodozText
ainda aponta para a string original (vazia).impressões:
Se você deseja modificar a string, pode usar como observado,
StringBuilder
ou algum contêiner (uma matriz ou umaAtomicReference
classe de contêiner personalizada) que fornece um nível adicional de indireto de ponteiro. Como alternativa, basta retornar o novo valor e atribuí-lo:impressões:
Essa é provavelmente a solução mais parecida com Java no caso geral - consulte o item Java eficaz "Favor da imutabilidade".
Porém, conforme observado,
StringBuilder
muitas vezes proporcionará um melhor desempenho - se você tiver muito o que fazer, especialmente dentro de um loop, useStringBuilder
.Mas tente passar imutável, em
Strings
vez de mutável,StringBuilders
se puder - seu código será mais fácil de ler e mais sustentável. Considere criar seus parâmetrosfinal
e configurar seu IDE para avisá-lo quando você reatribuir um parâmetro de método para um novo valor.fonte
String é um objeto imutável em Java. Você pode usar a classe StringBuilder para executar o trabalho que está tentando realizar, da seguinte maneira:
Outra opção é criar uma classe com uma String como uma variável de escopo (altamente desencorajada) da seguinte maneira:
fonte
A resposta é simples. Em Java, as strings são imutáveis. Portanto, é como usar o modificador 'final' (ou 'const' em C / C ++). Portanto, uma vez atribuído, você não pode alterá-lo da maneira que fez.
Você pode alterar qual valor para o qual uma string aponta, mas NÃO pode alterar o valor real para o qual essa string está apontando no momento.
Ou seja.
String s1 = "hey"
. Você pode criars1 = "woah"
, e isso é totalmente aceitável, mas na verdade não é possível alterar o valor subjacente da string (neste caso: "ei") para ser outra coisa uma vez atribuída usando plusEquals, etc. (ou seja,s1 += " whatup != "hey whatup"
).Para fazer isso, use as classes StringBuilder ou StringBuffer ou outros contêineres mutáveis e chame .toString () para converter o objeto novamente em uma string.
note: As strings são frequentemente usadas como chaves de hash, portanto, isso é parte da razão pela qual são imutáveis.
fonte
=
em uma referência NUNCA afeta o objeto usado para apontar, independentemente da classe.String é uma classe especial em Java. É Thread Safe, o que significa "Depois que uma instância de String é criada, o conteúdo da instância de String nunca será alterado".
Aqui está o que está acontecendo
Primeiro, o compilador Java obterá o valor da instância do zText String e, em seguida, criará uma nova instância do String cujo valor é o zText acrescentando "foo". Então você sabe por que a instância para a qual o zText aponta não mudou. É totalmente uma nova instância. De fato, mesmo String "foo" é uma nova instância de String. Portanto, para esta declaração, o Java criará duas instâncias de String, uma é "foo", outra é o valor do zText, anexado "foo". A regra é simples: o valor da instância String nunca será alterado.
Para o método fillString, você pode usar um StringBuffer como parâmetro ou pode alterá-lo assim:
fonte
Strings são imutáveis em Java.
fonte
Isso funciona usando StringBuffer
Melhor ainda usar o StringBuilder
fonte
String é imutável em java. você não pode modificar / alterar, uma string / objeto existente existente.
String s = "Olá"; s = s + "oi";
Aqui a referência anterior s é substituída pela nova referência s apontando para o valor "HelloHi".
No entanto, para trazer mutabilidade, temos StringBuilder e StringBuffer.
StringBuilder s = novo StringBuilder (); s.append ("Oi");
isso acrescenta o novo valor "Hi" à mesma referência s. //
fonte
Aaron Digulla tem a melhor resposta até agora. Uma variação de sua segunda opção é usar a classe wrapper ou container MutableObject da biblioteca commang lang versão 3+:
você salva a declaração da classe de contêiner. A desvantagem é uma dependência dos comuns lang lib. Mas a lib tem muitas funções úteis e quase qualquer projeto maior em que trabalhei a utilizou.
fonte
Para passar um objeto (incluindo String) por referência em java, você pode transmiti-lo como membro de um adaptador circundante. Uma solução com um genérico está aqui:
fonte
Para alguém que é mais curioso
fonte