Java Sintaxe e Estrutura
Toda língua tem gramática. No português, uma vírgula fora do lugar raramente impede alguém de entender a frase; no Java, impede o programa de existir. A sintaxe é o conjunto de regras de escrita do Java: onde vai cada símbolo, quais nomes valem, o que diferencia maiúscula de minúscula. Nesta aula você aprende as regras que valem para todo programa e as convenções que fazem o seu código parecer escrito por um programador Java.
- A estrutura de um programa: classe, métodos e instruções.
- Onde vai o ponto e vírgula e para que servem as chaves.
- Por que
Systemesystemsão coisas diferentes. - O que o Java faz com espaços, quebras de linha e recuo.
- As regras para criar nomes (identificadores) e as convenções camelCase, PascalCase e CONSTANTES.
- O que são palavras reservadas.
A ideia: regras e costumes
Na escrita, há dois tipos de regra. As da gramática são obrigatórias: "eu vai" está errado. As de estilo são costumes: começar uma carta com "Prezada Ana" não é obrigatório, mas todo mundo espera.
O Java é igual:
- Regras de sintaxe são obrigatórias. Quebrou uma, o
javacrecusa o programa com um erro. - Convenções são costumes da comunidade Java: o código compila sem elas, mas fica estranho e difícil de ler para outros programadores.
Esta aula marca cada item como regra ou convenção.
A estrutura de um programa
Todo programa Java tem a mesma organização, em camadas, como bonecas russas:
arquivo Loja.java
└── classe Loja public class Loja { … }
└── método main public static void main(String[] args) { … }
├── instrução String cliente = "Ana";
├── instrução int macas = 3;
└── instrução System.out.println(…);
public class Loja {
public static void main(String[] args) {
String cliente = "Ana";
int macas = 3;
System.out.println("Cliente: " + cliente);
System.out.println("Maçãs: " + macas);
}
}
$ java Loja.java Cliente: Ana Maçãs: 3
| Camada | O que é | Neste programa |
|---|---|---|
| Classe | O recipiente de tudo. Um arquivo tem pelo menos uma; a pública dá nome ao arquivo. | public class Loja { … } |
| Método | Um bloco de instruções com nome. O main é por onde o programa começa. | main |
| Instrução | Uma ordem completa, terminada em ;. Roda na ordem em que aparece, de cima para baixo. | as quatro linhas do meio |
| Expressão | Um pedaço de uma instrução que produz um valor. | "Cliente: " + cliente, 3 |
Instruções só podem ficar dentro de métodos (regra). Um System.out.println solto dentro da classe, fora do main, não compila. O significado de cada palavra da moldura está em Olá, Mundo; variáveis como cliente e macas, em Variáveis.
O ponto e vírgula ; (regra)
Toda instrução termina com ;. Não importa se ela ocupa meia linha ou três: o Java não olha para o fim da linha, olha para o ;.
Por isso, uma instrução comprida pode ser quebrada em várias linhas, e várias instruções podem ficar na mesma linha:
public class Main {
public static void main(String[] args) {
System.out.println("Uma instrução "
+ "em duas linhas");
System.out.println("Oi"); System.out.println("Tudo numa linha");
}
}
$ java Main.java Uma instrução em duas linhas Oi Tudo numa linha
As duas formas compilam. A primeira é útil para linhas muito compridas. A segunda é permitida, mas a convenção é uma instrução por linha, para ler fácil.
Sem o ;, o javac não sabe onde a instrução termina:
$ javac Main.java
Main.java:3: error: ';' expected
int nota = 8
^
1 error
Repare: o ^ aponta para logo depois do 8, onde o ; deveria estar, e a linha citada (3) é a da instrução sem ;. O que não leva ponto e vírgula: a linha que abre uma classe ou um método (termina em {) e as chaves }.
Blocos e chaves { } (regra)
As chaves agrupam código num bloco. A classe tem um bloco; cada método, outro; mais tarde, cada if e cada laço terão o seu. Toda { precisa da sua }, e elas se fecham na ordem inversa da abertura: a última aberta é a primeira fechada.
Falta de chave e chave sobrando dão erros diferentes:
| Problema | Mensagem do javac |
|---|---|
Faltou uma } no fim | reached end of file while parsing ("o arquivo acabou enquanto eu lia") |
Sobrou uma } | class, interface, annotation type, enum, record, method or field expected ("esperava uma classe, interface… aqui") |
public class Main {
public static void main(String[] args) {
String nome = "Ana";
System.out.println(nome);
}
}}
$ javac Main.java Main.java:6: error: class, interface, annotation type, enum, record, method or field expected }} ^ 1 error
A primeira } da linha 6 fechou a classe. Depois dela, fora de qualquer classe, o Java só aceita começar outra coisa (uma classe, uma interface…), e encontrou mais uma }. A aula Lendo Erros do javac mostra o caso da chave faltando.
Maiúsculas e minúsculas importam (regra)
Para o Java, System, system e SYSTEM são três nomes completamente diferentes, tanto quanto "casa" e "cama". Isso se chama ser sensível a maiúsculas (em inglês, case-sensitive). Cada troca dá um erro diferente:
| Você escreveu | Certo | O javac diz |
|---|---|---|
system.out.println("Oi"); | System | error: package system does not exist |
System.out.Println("Oi"); | println | error: cannot find symbol … symbol: method Println(String) |
string nome = "Ana"; | String | error: cannot find symbol … symbol: class string |
Public class Main { | public | error: class, interface, annotation type, enum, record, method or field expected |
System.out.println(Idade); (a variável é idade) | idade | error: cannot find symbol … symbol: variable Idade |
A mensagem do primeiro é curiosa: "o pacote system não existe". Com minúscula, o Java não reconhece a classe System e tenta entender system.out como um pacote (uma pasta de classes, veja Pacotes e import). Por isso a mensagem fala de pacote, e não de letra errada.
A mesma regra vale para os seus nomes. Duas variáveis que diferem só na maiúscula são duas variáveis diferentes:
int nota = 7; int Nota = 9; // outra variável! System.out.println(nota + " e " + Nota); // mostra: 7 e 9
Compila, mas é uma armadilha para quem lê. Não faça isso de propósito.
Missão: este programa tem três erros de maiúscula/minúscula. Rode, leia a mensagem, conserte um de cada vez até o programa mostrar as duas linhas.
public class Main {
public static void main(String[] args) {
string nome = "Ana";
system.out.println("Olá, " + nome + "!");
System.out.Println("Seu pedido: 3 maçãs");
}
}
public class Main {
public static void main(String[] args) {
String nome = "Ana";
System.out.println("Olá, " + nome + "!");
System.out.println("Seu pedido: 3 maçãs");
}
}
Espaços, quebras de linha e recuo
Fora dos textos entre aspas, o Java trata espaços, tabs e quebras de linha como simples separadores ((regra)): um espaço ou dez dá na mesma. Até isto compila e funciona:
System . out . println ( "espaços em volta do ponto" ) ;
Mas um espaço dentro de um nome quebra o nome em dois:
$ javac Main.java
Main.java:3: error: ';' expected
Sys tem.out.println("Oi");
^
1 error
O Java leu Sys e tem.out.println(...) como duas coisas separadas e esperava um ; entre elas. Dentro das aspas, ao contrário, cada espaço conta e aparece na tela.
Recuo (indentação) (convenção)
O recuo no começo das linhas não muda nada para o Java, mas muda tudo para quem lê. Compare o mesmo programa, que compila igual:
public class Main { public static void main(String[] args) { System.out.println("Oi"); System.out.println("Tudo numa linha"); } }
public class Main {
public static void main(String[] args) {
System.out.println("Oi");
System.out.println("Tudo numa linha");
}
}
As convenções de formatação do Java:
- 4 espaços a cada nível de bloco (o
mainfica 4 espaços para dentro da classe; as instruções, 8). - A
{fica no fim da linha que abre o bloco, não sozinha na linha de baixo. - A
}fica sozinha, alinhada com o começo da linha que abriu o bloco. - Uma instrução por linha.
- Espaço dos dois lados de
=e+:int total = a + b;.
Editores de código e IDEs fazem o recuo sozinhos (veja Editores e IDEs). Com o recuo certo, uma chave faltando salta aos olhos.
Brinque com o código: este programa está todo torto, mas compila. Rode. Depois arrume o recuo seguindo as convenções (4 espaços por nível, uma instrução por linha) e rode de novo: a saída não muda.
public class Main {
public static void main(String[] args) {
System.out.println("Loja da Ana"); System.out.println("Aberta das 8h às 18h");
System.out.println( "Volte sempre!" );
}
}
Identificadores: as regras dos nomes (regra)
Um identificador é qualquer nome que você cria: de classe, de variável, de método. As regras:
| Regra | Vale | Não vale |
|---|---|---|
Usa letras, dígitos, _ e $ | nota1, nota_final, valor$ | nota-final, nota final, nota! |
| Não começa com dígito | notas2, segundaNota | 2notas |
| Não pode ser palavra reservada | classe, minhaClasse | class, int, public |
| Maiúsculas importam | nota e Nota são dois nomes | |
| Letras acentuadas são permitidas | preço, média (compilam) |
Os erros de nome são confusos, porque o javac não diz "nome inválido": ele tenta entender o código de outra forma e reclama do que não fez sentido. Três exemplos reais:
$ javac Main.java « int 2notas = 10;
Main.java:3: error: not a statement
int 2notas = 10;
^
Main.java:3: error: ';' expected
int 2notas = 10;
^
2 errors
$ javac Main.java « int class = 10;
Main.java:3: error: not a statement
int class = 10;
^
Main.java:3: error: ';' expected
int class = 10;
^
Main.java:3: error: <identifier> expected
int class = 10;
^
3 errors
$ javac Main.java « int nota-final = 10;
Main.java:3: error: ';' expected
int nota-final = 10;
^
Main.java:3: error: illegal start of type
int nota-final = 10;
^
2 errors
No último, o Java leu nota-final como "nota menos final": o hífen é o sinal de subtração. Quando um erro aparece numa linha que declara um nome, desconfie do nome. A mensagem <identifier> expected ("esperava um identificador") é a pista mais direta.
O Java aceita preço e média como nomes, e o guia testou: compila e funciona. Mesmo assim, a convenção é usar só letras sem acento nos nomes (preco, media): teclados de outros países, ferramentas antigas e arquivos salvos em outra codificação (veja Editores e IDEs) podem se atrapalhar. Nos textos entre aspas, use acentos à vontade.
Missão: os nomes das variáveis estão inválidos. Troque 2notas por duasNotas e nota-extra por notaExtra (nas duas linhas em que cada um aparece) para o programa mostrar Total: 17.
public class Main {
public static void main(String[] args) {
int 2notas = 15;
int nota-extra = 2;
System.out.println("Total: " + (2notas + nota-extra));
}
}
public class Main {
public static void main(String[] args) {
int duasNotas = 15;
int notaExtra = 2;
System.out.println("Total: " + (duasNotas + notaExtra));
}
}
Convenções de nomes (convenção)
Dentro das regras, você pode escolher qualquer nome. Mas os programadores Java seguem um padrão tão firme que um nome fora dele parece erro. O padrão depende do que está sendo nomeado:
| O que | Estilo | Como é | Exemplos |
|---|---|---|---|
| Classes (e records, enums, interfaces) | PascalCase | Cada palavra começa com maiúscula, inclusive a primeira | Main, Loja, ContaBancaria, String |
| Variáveis e métodos | camelCase | Primeira palavra minúscula; as seguintes com maiúscula | nome, precoTotal, calcularMedia, println |
Constantes (static final) | MAIÚSCULAS_COM_SUBLINHADO | Tudo maiúsculo, palavras separadas por _ | MAX_ALUNOS, TAXA_DE_ENTREGA, Math.PI |
| Pacotes | minúsculas | Tudo minúsculo, separado por pontos | java.util, br.com.lojadaana |
camelCase vem de camel, "camelo": as maiúsculas no meio parecem corcovas (precoTotalDoPedido). PascalCase homenageia a linguagem Pascal, que popularizou o estilo. Por causa dessas convenções, só de olhar você sabe que String é uma classe, nome é uma variável e MAX_ALUNOS é uma constante (veja Constantes).
Bons nomes
- Diga o que é:
precoTotalé melhor quept,xouvalor2. - Métodos fazem coisas: comece com um verbo:
calcularMedia,mostrarRecibo. - Uma língua só: o guia nomeia em português (
nota,cliente); muitas empresas usam inglês. O importante é não misturar (notaFinalcomtotalPrice). - Evite
_e$em nomes comuns: o$é usado pelo próprio Java em nomes que ele gera, e o_sozinho é palavra reservada.
Palavras reservadas
Algumas palavras têm significado fixo no Java e não podem ser usadas como nomes: as palavras reservadas (keywords, "palavras-chave"). Você já conhece algumas:
| Para que | Palavras |
|---|---|
| Classes e acesso | class, public, private, protected, static, final, abstract, interface, enum, extends, implements, new, this, super, package, import |
| Tipos | int, long, short, byte, double, float, char, boolean, void |
| Decisões e repetições | if, else, switch, case, default, for, while, do, break, continue, return |
| Erros | try, catch, finally, throw, throws |
| Valores fixos (literais) | true, false, null |
Todas são escritas em minúsculas. Há ainda palavras "reservadas só em certos lugares", como var, record e yield: elas têm significado especial em alguns pontos do código, mas ainda podem ser nomes de variável (o guia testou int var = 3; e int record = 4;: compilam). Não use, para não confundir. A lista completa, com o que cada uma faz, está na Referência de Palavras-chave.
Referência
| Item | Tipo | Resumo |
|---|---|---|
| Instruções dentro de métodos | regra | Nada de println solto na classe. |
; no fim de cada instrução | regra | Não depois de { nem de }. |
Toda { com a sua } | regra | Faltou: reached end of file. Sobrou: class, interface… expected. |
| Maiúsculas importam | regra | System, String, println, public. |
Nomes: letras, dígitos, _, $; não começam com dígito; não são palavras reservadas | regra | nota1 sim; 1nota, nota-1, class não. |
Recuo de 4 espaços, { no fim da linha | convenção | O Java ignora; as pessoas não. |
| PascalCase, camelCase, MAIÚSCULAS | convenção | Classes, variáveis/métodos, constantes. |
Exercícios
1. Corrija a maiúscula
Complete com o nome certo da classe que escreve na tela:
2. camelCase
Escreva em camelCase o nome de uma variável para "preço total do pedido" (sem acentos):
3. Qual destes é um nome de variável válido?
4. Pela convenção, qual nome é de uma classe?
5. O javac respondeu error: package system does not exist. Qual é o erro mais provável?
6. O recuo (os espaços no começo das linhas) é obrigatório no Java?
Resumo
- Programa = classe ⊃ métodos ⊃ instruções. Instruções só dentro de métodos e rodam de cima para baixo.
- Toda instrução termina em
;; o fim da linha não importa para o Java. - Chaves agrupam blocos e precisam fechar na ordem certa.
- Maiúsculas importam:
System≠system,nota≠Nota. - Espaços e quebras de linha são livres fora das aspas; dentro de um nome, quebram o nome.
- Nomes: letras, dígitos,
_e$, sem começar com dígito, sem palavras reservadas. - Convenções: PascalCase para classes, camelCase para variáveis e métodos, MAIÚSCULAS_COM_SUBLINHADO para constantes, recuo de 4 espaços.