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.

Você vai aprender
  • 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 System e system sã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 javac recusa 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
CamadaO que éNeste programa
ClasseO recipiente de tudo. Um arquivo tem pelo menos uma; a pública dá nome ao arquivo.public class Loja { … }
MétodoUm bloco de instruções com nome. O main é por onde o programa começa.main
InstruçãoUma ordem completa, terminada em ;. Roda na ordem em que aparece, de cima para baixo.as quatro linhas do meio
ExpressãoUm 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:

ProblemaMensagem do javac
Faltou uma } no fimreached 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ê escreveuCertoO javac diz
system.out.println("Oi");Systemerror: package system does not exist
System.out.Println("Oi");printlnerror: cannot find symbol … symbol: method Println(String)
string nome = "Ana";Stringerror: cannot find symbol … symbol: class string
Public class Main {publicerror: class, interface, annotation type, enum, record, method or field expected
System.out.println(Idade); (a variável é idade)idadeerror: 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 main fica 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:

RegraValeNão vale
Usa letras, dígitos, _ e $nota1, nota_final, valor$nota-final, nota final, nota!
Não começa com dígitonotas2, segundaNota2notas
Não pode ser palavra reservadaclasse, minhaClasseclass, int, public
Maiúsculas importamnota e Nota são dois nomes
Letras acentuadas são permitidaspreç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.

Acentos: pode, mas evite

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 queEstiloComo éExemplos
Classes (e records, enums, interfaces)PascalCaseCada palavra começa com maiúscula, inclusive a primeiraMain, Loja, ContaBancaria, String
Variáveis e métodoscamelCasePrimeira palavra minúscula; as seguintes com maiúsculanome, precoTotal, calcularMedia, println
Constantes (static final)MAIÚSCULAS_COM_SUBLINHADOTudo maiúsculo, palavras separadas por _MAX_ALUNOS, TAXA_DE_ENTREGA, Math.PI
PacotesminúsculasTudo minúsculo, separado por pontosjava.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 que pt, x ou valor2.
  • 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 (notaFinal com totalPrice).
  • 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 quePalavras
Classes e acessoclass, public, private, protected, static, final, abstract, interface, enum, extends, implements, new, this, super, package, import
Tiposint, long, short, byte, double, float, char, boolean, void
Decisões e repetiçõesif, else, switch, case, default, for, while, do, break, continue, return
Errostry, 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

ItemTipoResumo
Instruções dentro de métodosregraNada de println solto na classe.
; no fim de cada instruçãoregraNão depois de { nem de }.
Toda { com a sua }regraFaltou: reached end of file. Sobrou: class, interface… expected.
Maiúsculas importamregraSystem, String, println, public.
Nomes: letras, dígitos, _, $; não começam com dígito; não são palavras reservadasregranota1 sim; 1nota, nota-1, class não.
Recuo de 4 espaços, { no fim da linhaconvençãoO Java ignora; as pessoas não.
PascalCase, camelCase, MAIÚSCULASconvençãoClasses, variáveis/métodos, constantes.

Exercícios

1. Corrija a maiúscula

Complete com o nome certo da classe que escreve na tela:

.out.println("Oi");

2. camelCase

Escreva em camelCase o nome de uma variável para "preço total do pedido" (sem acentos):

double = 42.5;

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.