Até hoje, pensei que, por exemplo:
i += j;
Foi apenas um atalho para:
i = i + j;
Mas se tentarmos isso:
int i = 5;
long j = 8;
Então i = i + j;
não irá compilar, mas i += j;
irá compilar bem.
Isso significa que, de fato, i += j;
é um atalho para algo assim
i = (type of i) (i + j)
?
java
casting
operators
variable-assignment
assignment-operator
Honza Brabec
fonte
fonte
i+=(long)j;
mesmo compilará bem.i += (int) f;
lança f antes da adição, portanto não é equivalente.(int) i += f;
lança o resultado após a atribuição, também não é equivalente. não haveria lugar para colocar uma conversão que significaria que você deseja converter o valor após adicionar, mas antes da atribuição.Respostas:
Como sempre com essas perguntas, o JLS mantém a resposta. Nesse caso, §15.26.2 Operadores de atribuição composta . Um extrato:
Um exemplo citado em §15.26.2
Em outras palavras, sua suposição está correta.
fonte
i+=j
compila como eu me verifiquei, mas resultaria em perda de precisão, certo? Se for esse o caso, por que não permite que isso aconteça em i = i + j também? Por que nos incomodar lá?i += j
), é mais seguro assumir que a perda de precisão é desejado em oposição ao outro caso (i = i + j
)E1 op= E2 is equivalent to E1 = (T)((E1) op (E2))
isso é como uma conversão de texto implícita para baixo (do longo para o int). Enquanto em i = i + j, temos que fazê-lo explicitamente, ou seja, fornecer a(T)
parte emE1 = ((E1) op (E2))
Não é?Um bom exemplo dessa transmissão é usar * = ou / =
ou
ou
ou
fonte
A
;)ch += 32
= DMuito boa pergunta. A especificação da linguagem Java confirma sua sugestão.
fonte
double->float
como ampliadoras, com base em que os valores do tipofloat
identificam números reais menos especificamente do que os do tipodouble
. Se alguém visualizardouble
como um endereço postal completo efloat
um código postal de cinco dígitos, é possível atender a uma solicitação de código postal com um endereço completo, mas não é possível especificar com precisão uma solicitação de endereço completo, apenas com um código postal . Convertendo um endereço com um código postal é uma operação com perdas, mas ...float->double
é equivalente a converter o código postal dos EUA 90210 com "Agência dos EUA, Beverly Hills CA 90210".Sim,
basicamente quando escrevemos
o compilador converte isso em
Acabei de verificar o
.class
código do arquivo.Realmente uma coisa boa de saber
fonte
você precisa converter de
long
paraint
explicitly
em caso dei = i + l
compilação e saída correta. gostarou
mas, no caso
+=
disso, funciona bem, porque o operador faz implicitamente a conversão de tipo do tipo da variável direita para o tipo da variável esquerda, portanto, não é necessário converter explicitamente.fonte
int
é realizado após o+
. O compilador lançaria (deveria?) Um aviso se realmente lançou olong
paraint
.O problema aqui envolve a conversão de tipos.
Quando você adiciona int e long,
Mas
+=
é codificado de tal maneira que faz a conversão de tipo.i=(int)(i+m)
fonte
No Java, as conversões de tipo são executadas automaticamente quando o tipo da expressão no lado direito de uma operação de atribuição pode ser promovido com segurança para o tipo de variável no lado esquerdo da atribuição. Assim, podemos atribuir com segurança:
O mesmo não funcionará ao contrário. Por exemplo, não podemos converter automaticamente um longo para um int porque o primeiro requer mais armazenamento que o segundo e, consequentemente, as informações podem ser perdidas. Para forçar essa conversão, devemos realizar uma conversão explícita.
Tipo - Conversão
fonte
long
é 2 vezes maior quefloat
.float
não pode conter todos osint
valores possíveis e adouble
não pode armazenar todos oslong
valores possíveis .double d=33333333+1.0f;
sem reclamação, mesmo que o resultado 33333332.0 provavelmente não seja o que se pretendia (aliás, a resposta aritmeticamente correta de 33333334.0f seria representável comofloat
ouint
).Às vezes, essa pergunta pode ser feita em uma entrevista.
Por exemplo, quando você escreve:
não há conversão automática de texto. Em C ++, não haverá nenhum erro ao compilar o código acima, mas em Java você terá algo parecido
Incompatible type exception
.Portanto, para evitá-lo, você deve escrever seu código assim:
fonte
op
uso em C ++ com o uso em Java. Eu sempre gosto de ver essas curiosidades e acho que elas contribuem com algo para a conversa que pode ser deixada de fora.A principal diferença é que
a = a + b
, com , não há transmissão de texto em andamento e, portanto, o compilador fica com raiva de você por não ter feito a transmissão. Mas coma += b
o que realmente está fazendo é converterb
para um tipo compatívela
. Então se você fazO que você realmente está fazendo é:
fonte
Ponto sutil aqui ...
Há uma conversão implícita de
i+j
quandoj
é um duplo ei
é um int. Java SEMPRE converte um número inteiro em um duplo quando houver uma operação entre eles.Para esclarecer
i+=j
ondei
é um número inteiro ej
é um duplo, pode ser descrito comoVeja: esta descrição da conversão implícita
Você pode querer estereotipado
j
para(int)
, neste caso, para maior clareza.fonte
int someInt = 16777217; float someFloat = 0.0f; someInt += someFloat;
. Adicionar zero asomeInt
não deve afetar seu valor, mas promoversomeInt
afloat
pode mudar seu valor.Especificação de linguagem Java define
E1 op= E2
como equivalente aE1 = (T) ((E1) op (E2))
ondeT
é um tipo deE1
eE1
é avaliada uma vez .Essa é uma resposta técnica, mas você pode estar se perguntando por que esse é o caso. Bem, vamos considerar o seguinte programa.
O que esse programa imprime?
Você adivinhou 3? Pena que este programa não será compilado. Por quê? Bem, acontece que a adição de bytes em Java é definida para retornar um
int
. Acredito que isso ocorreu porque a Java Virtual Machine não define operações de byte para economizar em bytecodes (há um número limitado delas, afinal), usar operações inteiras é um detalhe de implementação exposto em uma linguagem.Mas se
a = a + b
não funcionar, isso significariaa += b
que nunca funcionaria para bytes seE1 += E2
fosse definidoE1 = E1 + E2
. Como mostra o exemplo anterior, esse seria realmente o caso. Como um truque para fazer o+=
operador trabalhar para bytes e curtos, há uma conversão implícita envolvida. Não é tão bom assim, mas, durante o trabalho do Java 1.0, o foco estava em liberar a linguagem para começar. Agora, devido à compatibilidade com versões anteriores, esse hack introduzido no Java 1.0 não pôde ser removido.fonte