A concatenação de caracteres para formar uma string fornece resultados diferentes

Por que, quando eu uso a operação abaixo para sumr caracteres, ele retorna números em vez de chars? Não deveria dar o mesmo resultado?

ret += ... ; // returns numbers ret = ret + ...; // returns chars 

O código abaixo duplica os caracteres:

doubleChar (“The”) → “TThhee”

 public String doubleChar(String str) { String ret = ""; for(int i = 0; i < str.length(); i++) { ret = ret + str.charAt(i) + str.charAt(i); // it concatenates the letters correctly //ret += str.charAt(i) + str.charAt(i); // it concatenates numbers } return ret; } 

O resultado da seguinte expressão

 ret + str.charAt(i) + str.charAt(i); 

é o resultado da concatenação de strings. Os estados da especificação da linguagem Java

O resultado da concatenação de cadeias de caracteres é uma referência a um object String que é a concatenação das duas cadeias de operandos. Os caracteres do operando esquerdo precedem os caracteres do operando direito na string recém-criada.

O resultado de

 str.charAt(i) + str.charAt(i); 

é o resultado do operador aditivo aplicado a dois tipos numéricos. Os estados da especificação da linguagem Java

O operador binário + realiza a adição quando aplicado a dois operandos do tipo numérico, produzindo a sum dos operandos. […] O tipo de uma expressão aditiva em operandos numéricos é o tipo promovido de seus operandos.

Nesse caso,

 str.charAt(i) + str.charAt(i); 

torna-se um int mantendo a sum dos dois valores char . Isso é então concatenado para ret .


Você também pode querer saber isso sobre a expressão de atribuição composta +=

Uma expressão de atribuição composta da forma E1 op= E2 é equivalente a E1 = (T) ((E1) op (E2)) , onde T é o tipo de E1 , exceto que E1 é avaliado apenas uma vez.

Em outras palavras

 ret += str.charAt(i) + str.charAt(i); 

é equivalente a

 ret = (String) ((ret) + (str.charAt(i) + str.charAt(i))); | ^ integer addition | ^ string concatenation 

No seu primeiro exemplo, você está adicionando explicitamente uma String como o primeiro termo. Isso força o segundo e terceiro termo a ser promovido a String (s). No segundo caso, você está adicionando dois caracteres (que são anexados à String) – ele não promove a uma String até a atribuição. Você poderia ter sido explícito, usando Character.toString () ou String.valueOf () assim

 ret += Character.toString(str.charAt(i)) + String.valueOf(str.charAt(i)); 

O primeiro exemplo

Da semântica, eu diria que estamos olhando para arithmetic promotion no trabalho. Observe o primeiro exemplo:

 String + char + char 

Devido à promoção aritmética, esses dois valores char são promovidos para valores String , portanto, os tipos se tornam:

 String + String + String 

O + está sobrecarregado para executar a concatenação porque todos os operandos são do tipo String .

O segundo exemplo

No segundo exemplo, como em todas as tarefas, avaliamos o lado direito do operador = primeiro e o que temos?

 char + char 

O char é interpretado como seu valor numérico, porque não há String para causar promoção e temos uma adição numérica, que é então anexada à String .

Leitura extra

Algumas notas sobre promoção aritmética podem ser encontradas aqui .

Algumas notas sobre avaliação de expressão podem ser encontradas aqui .

Da especificação de Java :

15.26.2. Operadores de Atribuição Composta

Uma expressão de atribuição composta da forma E1 op= E2 é equivalente a E1 = (T) ((E1) op (E2)) , onde T é o tipo de E1 , exceto que E1 é avaliado apenas uma vez.

Portanto, o operador += tem uma conversão interna para o tipo de destino.

Em contraste, a cláusula para atribuição simples diz :

15.26.1. Operador de Atribuição Simples =

Ocorre um erro em tempo de compilation se o tipo de operando à direita não puder ser convertido para o tipo da variável por conversão de atribuição (§5.2).

Aqui,

  ret = ret + str.charAt(i) + str.charAt(i); 

é tratado como uma concatenação de strings.

E

 ret += str.charAt(i) + str.charAt(i); 

é tratado como operação aditiva.

ret = ret + str.charAt (i) + str.charAt (i); // // concatena as letras corretamente

Isso ocorre porque ret é string e concatena com os outros caracteres.

ret + = str.charAt (i) + str.charAt (i); // concatena números

Isso ocorre porque o compilador avalia primeiro ‘str.charAt (i) + str.charAt (i)’, o que provavelmente resulta em um número e, em seguida, o concatena com ret. Então, basicamente, avaliamos o lado esquerdo e depois o atribuímos.

Espero que isso limpe sua confusão.