O que os operadores fazem
Operadores são os símbolos que combinam valores para calcular outros novos. Você já os usa de forma intuitiva - + soma, > compara - e o Java os agrupa em algumas famílias: aritméticos, de comparação, lógicos, de atribuição, e alguns especiais como o incremento e o ternário.
A maioria dos operadores recebe dois valores (um antes e um depois do símbolo) e produz um resultado. O segredo está em saber qual é o tipo desse resultado e a ordem em que eles se aplicam - é aí que os iniciantes escorregam.
Operadores aritméticos
Os cinco operadores aritméticos trabalham com números: +, -, *, / e % (resto).
O operador % é o resto após a divisão: 17 % 5 é 2 porque o 5 cabe três vezes no 17 e sobram 2. É a ferramenta do dia a dia para testar divisibilidade - n % 2 == 0 é a verificação padrão de "n é par?".
Repare também que + tem função dupla: com números ele soma, mas com uma String em qualquer um dos lados ele junta texto.
A primeira linha é lida da esquerda para a direita: "Total: " + 3 já é uma string, então o 4 é anexado como texto. Coloque a conta entre parênteses quando quiser que ela seja calculada primeiro.
A pegadinha da divisão inteira
Essa é a surpresa mais comum de todas. Quando os dois operandos de / são inteiros, o Java faz divisão inteira e descarta a fração - ele não arredonda, ele trunca em direção a zero.
Para obter um resultado decimal, faça com que pelo menos um operando seja um double - ou escreva-o com um .0, ou faça um cast de um dos lados com (double). Fazer (double)(5 / 2) não ajuda, porque a divisão inteira 5 / 2 já aconteceu antes do cast; você precisa fazer o cast em um operando, não no resultado.
Operadores de comparação
Os operadores de comparação fazem uma pergunta de sim/não e devolvem um boolean. São seis: ==, !=, <, >, <=, >=.
Preste atenção na diferença entre = (atribuição - "coloque este valor aqui") e == (comparação - "estes são iguais?"). Confundir os dois é um bug clássico.
Uma ressalva importante: == compara referências de objetos, não conteúdos. Para strings, use .equals().
Use == para primitivos como int e boolean, e .equals() sempre que comparar o conteúdo de objetos como String.
Operadores lógicos
Os operadores lógicos combinam valores booleanos: && (e), || (ou) e ! (não). É assim que você expressa condições como "tem idade suficiente e tem ingresso".
&& e || fazem curto-circuito: o Java para de avaliar assim que a resposta é certa. Com &&, se o lado esquerdo for false o direito nunca é verificado; com ||, se o lado esquerdo for true o direito é ignorado. Isso não é só uma otimização - você pode se apoiar nisso por segurança:
if (text != null && text.length() > 0) { ... }
Se text for null, o lado esquerdo é false e text.length() nunca é chamado, evitando uma NullPointerException. Inverta a ordem e o programa quebraria.
Atribuição e incremento
= atribui, mas o Java também tem atribuições compostas que combinam uma operação com a atribuição: +=, -=, *=, /=, %=. E ++ / -- somam ou subtraem um.
++ vem em duas formas: pós-fixada (count++) devolve o valor antigo e depois incrementa; pré-fixada (++count) incrementa primeiro e depois devolve o novo valor. A diferença só importa quando você usa o resultado na mesma expressão:
Quando ++ está sozinho em uma linha, pós-fixada ou pré-fixada dá no mesmo - então prefira a que ficar mais clara de ler e não enfie incrementos dentro de expressões maiores.
O operador ternário
O ternário condition ? a : b é um if/else compacto que produz um valor: se a condição for true ele avalia para a, caso contrário para b.
Ele brilha em atribuições curtas de um-ou-outro. Resista a aninhar ternários dentro de ternários - isso fica ilegível rapidamente, e um if/else comum é mais claro.
Precedência e parênteses
Os operadores se aplicam em uma ordem fixa, bem parecida com a da matemática: *, /, % se ligam mais forte do que + e -, que se ligam mais forte do que as comparações, que se ligam mais forte do que &&, e por fim ||.
Você não precisa decorar a tabela inteira. Quando uma expressão mistura famílias ou você precisa parar para deduzir a ordem, adicione parênteses - eles não custam nada e deixam a intenção óbvia para quem ler depois.
Próximo: conversão de tipos
Várias das pegadinhas daqui - divisão inteira, misturar int e double - se resumem aos tipos. Converter entre tipos numéricos de forma deliberada se chama casting, e é disso que trata a próxima página.
Perguntas frequentes
O que o operador % faz em Java?
% é o operador de resto (módulo): ele devolve o que sobra depois de uma divisão inteira. 7 % 3 é 1, e 10 % 2 é 0. É a forma padrão de testar divisibilidade (n % 2 == 0 significa que n é par) e de encaixar um valor dentro de um intervalo.
Por que 5 / 2 dá 2 em Java em vez de 2.5?
Quando os dois operandos são inteiros, / faz divisão inteira e descarta a parte fracionária, então 5 / 2 é 2, não 2.5. Para obter 2.5 você precisa que pelo menos um operando seja um double: escreva 5.0 / 2, 5 / 2.0, ou faça um cast de um dos lados com (double) 5 / 2.
Qual é a diferença entre == e equals() em Java?
== compara primitivos por valor, mas para objetos (incluindo String) ele compara referências - se são o mesmo objeto na memória. Para comparar o conteúdo dos objetos, use .equals(). Comparar duas strings com == pode retornar false mesmo quando o texto coincide, então use sempre "a".equals(b) para strings.