UC00619

Desenvolver aplicações em linguagem Java

Algoritmos, POO, coleções, ficheiros, JDBC e testes

Curso profissional · 50h · Linguagem industrial

Plano

  1. Java e algoritmos
  2. Planeamento do desenvolvimento
  3. Ambiente de desenvolvimento e Maven
  4. Sintaxe básica
  5. Programação orientada por objetos
  6. Coleções
  7. Exceções
  8. Ficheiros e bases de dados (JDBC)
  9. Testes, depuração e documentação
Bloco 1 · Java e algoritmos

Pensar antes de programar

Java em contexto

  • Compilado para bytecode: corre na JVM em qualquer sistema.
  • Tipado estaticamente: erros de tipo apanhados em compilação.
  • Orientado por objetos, com recolha automática de memória.
  • Usado em backend empresarial, Android, big data e banca.
  • Não é a melhor escolha para scripts rápidos ou sistemas de baixo nível.

Do código à execução

Etapa Ferramenta Saída
Escrever Editor ou IDE App.java
Compilar javac App.class (bytecode)
Executar java (JVM) Resultado no ecrã
  • Erro de compilação: o .class não é gerado.
  • Erro de execução: rebenta com o programa a correr.
  • Erro lógico: corre, mas dá o resultado errado.

JDK, JRE, JVM e memória

  • JVM: executa o bytecode.
  • JRE: JVM mais bibliotecas standard.
  • JDK: JRE mais ferramentas (javac, javadoc).
  • Stack: variáveis locais e chamadas de métodos.
  • Heap: os objetos; a stack guarda só a referência.
  • O garbage collector liberta objetos sem referências.
String nome = "Ana";   // referência na stack
String outro = nome;   // duas referências, um só objeto

Pensamento computacional

Pilar Pergunta
Decomposição Como parto o problema em partes?
Padrões Já resolvi algo parecido?
Abstração O que é essencial?
Algoritmos Que passos, por ordem?

Exemplo: sistema de notas de uma turma.

Algoritmos: três estruturas

Um algoritmo é uma sequência finita, ordenada e não ambígua de passos.

  1. Sequência: passos por ordem.
  2. Seleção: se ... então ... senão.
  3. Repetição: enquanto a condição se mantiver.

Representa-se em linguagem natural, pseudocódigo ou fluxograma.

Exemplo: maior de três números

LER a, b, c
maior <- a
SE b > maior ENTÃO maior <- b
SE c > maior ENTÃO maior <- c
ESCREVER maior

Teste de mesa com a = 4, b = 9, c = 7:

Passo maior
maior <- a 4
9 > 4 9
7 > 9 9 (mantém)

Exemplo: número primo

static boolean ehPrimo(int n) {
    if (n < 2) return false;
    for (int d = 2; d * d <= n; d++) {
        if (n % d == 0) return false;
    }
    return true;
}
  • Basta testar divisores até à raiz de n.
  • d * d <= n evita calcular a raiz quadrada.
  • 2, 13 e 29 são primos; 9 e 25 não.
Bloco 2 · Planeamento

Do requisito à entrega

Fases do desenvolvimento

  1. Requisitos: o que o sistema faz.
  2. Análise e desenho: como se organiza.
  3. Implementação: código versionado.
  4. Testes: faz o que foi pedido?
  5. Entrega e documentação: guião técnico e manual.
  6. Manutenção: correções e evolução.

Cascata e metodologias ágeis

Aspeto Cascata Ágil (Scrum, Kanban)
Entregas Uma, no fim Várias, incrementais
Mudança Cara Esperada
Feedback No fim Em cada ciclo
Risco Descoberto tarde Descoberto cedo

Em Scrum, o trabalho faz-se em sprints de uma a quatro semanas.

Requisitos e histórias de utilizador

  • Funcional: o que o sistema faz.
  • Não funcional: como (desempenho, segurança, usabilidade).

Modelo de história:

Como [papel], quero [funcionalidade] para [benefício].

Exemplo: Como bibliotecário, quero registar um livro novo para o ter no catálogo.

Planear: dos nomes às classes

  • Os nomes das histórias sugerem classes: Livro, Leitor, Emprestimo.
  • Os verbos sugerem métodos: registar, emprestar, devolver.
Etapa Horas
Modelo de dados 2
Regras de negócio 2
Persistência 3
Interface de consola 2
Testes 2
Documentação 1

Diagrama de classes (UML)

+----------+     +-------------+     +---------+
|  Leitor  | 1 * | Emprestimo  | * 1 |  Livro  |
+----------+-----+-------------+-----+---------+
| - nome   |     | - data      |     | - titulo|
+----------+     +-------------+     +---------+
| + pedir()|     | + devolver()|     |         |
+----------+     +-------------+     +---------+
  • - é private, + é public.
  • 1 e * são a multiplicidade.

Desenhar a interface

=== Biblioteca da Escola ===
1. Registar livro
2. Emprestar livro
3. Devolver livro
4. Listar livros em atraso
0. Sair
Opção: _
  • Uma ação por opção de menu.
  • Feedback claro depois de cada ação.
  • Mensagens de erro que dizem o que fazer a seguir.
  • Validar a entrada e voltar a perguntar.

Normas, RGPD e licenças

  • Convenções de código: PascalCase, camelCase, UPPER_SNAKE_CASE.
  • RGPD: recolher o mínimo de dados pessoais e protegê-los; nunca guardar palavras-passe em texto simples.
  • Licenças: Apache 2.0, MIT, GPL definem o que podes fazer com uma biblioteca.
  • Direitos de autor: cita a fonte do código que adaptas.
Bloco 3 · Ambiente

JDK, IDE e Maven

O JDK e a versão

  • JDK 21 é uma versão de suporte prolongado (LTS).
  • Distribuições gratuitas: Adoptium Temurin, Amazon Corretto.
  • Variáveis: PATH e JAVA_HOME.
java --version
javac --version

Editor de texto ou IDE

Funcionalidade Editor IDE
Realce de sintaxe Sim Sim
Autocompletar Não Sim
Deteção de erros Não Sim
Depurador Não Sim
Refatoração Não Sim

IDEs: IntelliJ IDEA, Eclipse, VS Code com extensões de Java. Confirma no site oficial as condições de utilização gratuita em vigor.

Hello World

// HelloWorld.java
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Olá mundo!");
    }
}
javac HelloWorld.java   # gera HelloWorld.class
java HelloWorld

O ficheiro tem o nome exato da classe pública.

Anatomia do main

  • public: visível para a JVM.
  • static: pertence à classe, não precisa de objeto.
  • void: não devolve valor.
  • String[] args: argumentos da linha de comandos.

java App um dois dá args[0] igual a "um".

Depurar com o IDE

  1. Pôr um breakpoint na margem da linha.
  2. Executar em modo Debug.
  3. Step Over, Step Into, Step Out.
  4. Observar as variáveis e as watches.
  5. Encontrar a linha onde o valor passa de certo a errado.

Ler um erro do compilador

int x = "dez";            // linha 3
System.out.println(x)     // linha 4, falta o ;
Teste.java:4: error: ';' expected
  • A mensagem diz ficheiro, linha e causa.
  • Um erro de sintaxe pára a compilação: o erro de tipos da linha 3 ainda não aparece.
  • Corrigido o ;, surge Teste.java:3: error: incompatible types: String cannot be converted to int.
  • Recompila depois de cada correção.

Ler documentação técnica

  • A API (docs.oracle.com/en/java/javase/21/docs/api) tem uma página por classe.
  • Ordem fixa: descrição, construtores, métodos (assinatura, parâmetros, devolve, exceções).
  • Tutoriais, manuais de ferramentas, README e pom.xml também se leem.
// ArrayList: removeIf(Predicate<? super E> filter) devolve boolean
var notas = new ArrayList<>(List.of(8, 15, 6, 12));
boolean mudou = notas.removeIf(n -> n < 10);
// notas = [15, 12], mudou = true

Projeto Maven

minha-app/
├── pom.xml
└── src/
    ├── main/java/com/exemplo/App.java
    └── test/java/com/exemplo/AppTest.java
  • groupId, artifactId e version identificam o projeto.
  • O pacote com.exemplo corresponde às pastas com/exemplo.

Maven: comandos e dependências

mvn compile
mvn test
mvn package        # gera o .jar em target/
mvn clean install
  • Pedir uma fase executa todas as anteriores.
  • Se um teste falhar, o .jar não é criado.
  • scope test: biblioteca só para testes.
  • Versões das bibliotecas: escolhe a estável mais recente no Maven Central, numa propriedade do pom.xml.
Bloco 4 · Sintaxe

Dados, decisões e ciclos

Tipos primitivos

Tipo Tamanho
byte 8 bits
short 16 bits
int 32 bits
long 64 bits
float / double 32 / 64 bits
boolean true ou false
char 16 bits (Unicode)

String não é primitivo: é objeto.

Operadores e comparações

int div = 10 / 3;          // 3 (divisão inteira)
double real = 10.0 / 3;    // 3.333...
int mod = 10 % 3;          // 1

String a = "Ana";
a.equals("Ana");           // sempre assim para texto
  • == em objetos compara referências.
  • && e || avaliam em curto-circuito.

Conversão de tipos

int i = 7;
double d = i;               // automática: 7.0
int t = (int) 3.99;         // cast: 3 (corta)

int n = Integer.parseInt("42");
double v = Double.parseDouble("3.14");

parseInt("abc") lança NumberFormatException.

Decisões: if e switch

if (idade >= 18) {
    System.out.println("Adulto");
} else {
    System.out.println("Menor");
}

String tipo = switch (dia) {
    case 1, 2, 3, 4, 5 -> "Útil";
    case 6, 7 -> "Fim de semana";
    default -> "Inválido";
};

Ciclos: for, while, do-while

for (int i = 0; i < 3; i++) { System.out.println(i); }

String[] nomes = {"Ana", "Bruno"};
for (String n : nomes) { System.out.println(n); }

int x;
do { x = sc.nextInt(); } while (x < 0);
  • for: número de repetições conhecido.
  • while: repete até a condição mudar.
  • do-while: corre pelo menos uma vez.

Arrays

int[] v = {1, 2, 3, 4, 5};
int n = v.length;            // 5
v[0] = 10;
int ultimo = v[v.length - 1];

int[][] m = {{1, 2, 3}, {4, 5, 6}};
int x = m[1][2];             // 6
  • Índices de 0 a length - 1.
  • Tamanho fixo; para crescer, usa ArrayList.

Métodos e sobrecarga

static int somar(int a, int b) { return a + b; }

static double somar(double a, double b) {
    return a + b;
}
  • Mesmo nome com parâmetros diferentes é sobrecarga.
  • Os argumentos passam por valor.
  • Para objetos passa-se uma cópia da referência.
Bloco 5 · Programação orientada por objetos

Classes, relações e contratos

Classe, objeto, atributo, método, mensagem

public class Pessoa {
    private String nome;
    private int idade;

    public Pessoa(String nome, int idade) {
        this.nome = nome;
        this.idade = idade;
    }
    public void apresentar() {
        System.out.println("Sou " + nome);
    }
}

new Pessoa("Ana", 25) cria o objeto. p.apresentar() envia-lhe uma mensagem.

Encapsulamento

Modificador Visível em
private Só na classe
(nenhum) No pacote
protected Pacote e subclasses
public Em todo o lado
public void setIdade(int idade) {
    if (idade < 0) throw new IllegalArgumentException();
    this.idade = idade;
}

Construtores, this e static

public Pessoa()               { this("Anónimo", 0); }
public Pessoa(String nome)    { this(nome, 0); }
public Pessoa(String n, int i) { nome = n; idade = i; }
  • this(...) chama outro construtor.
  • static pertence à classe e é partilhado.
private static int total = 0;   // um só valor

Relações entre classes

Relação Significado
Dependência Usa de passagem
Associação Conhece
Agregação Tem um (partes independentes)
Composição É composto por (partes dependentes)
Herança É um (extends)
Realização Cumpre um contrato (implements)

Relações entre objetos

  • Um para um: Aluno e CartaoEstudante.
  • Um para muitos: Leitor e a sua lista de Emprestimo.
  • Muitos para muitos: Aluno e Disciplina, resolvido com uma classe Inscricao.
private final List<Emprestimo> emprestimos = new ArrayList<>();

Herança

public class Empregado extends Pessoa {
    private double salario;
    private String cargo;

    public Empregado(String nome, int idade, double salario, String cargo) {
        super(nome, idade);
        this.salario = salario;
        this.cargo = cargo;
    }
    @Override
    public void apresentar() {
        super.apresentar();
        System.out.println("Cargo: " + cargo + ", salário: " + salario + "€");
    }
}

Polimorfismo

Pessoa p = new Empregado("Ana", 25, 1000, "Dev");
p.apresentar();   // executa a versão de Empregado
List<Figura> figuras =
    List.of(new Circulo(1), new Retangulo(2, 3));
for (Figura f : figuras) {
    total += f.area();   // cada objeto responde à sua maneira
}

Classes abstratas e interfaces

Classe abstrata Interface
Atributos de instância Sim Não
Herança múltipla Não Sim
Construtor Sim Não
Uso Base comum com código Contrato transversal
public interface Veiculo {
    void acelerar();
    default void buzinar() { System.out.println("Beep!"); }
}

Records e enums

public record Ponto(double x, double y) { }

Ponto p = new Ponto(1, 2);
System.out.println(p);   // Ponto[x=1.0, y=2.0]

public enum Estado { DISPONIVEL, EMPRESTADO, PERDIDO }
  • O record gera construtor, acessores, equals, hashCode e toString.
  • O enum define um conjunto fechado de valores.

Classes genéricas

public class Caixa<T> {
    private T conteudo;
    public Caixa(T conteudo) { this.conteudo = conteudo; }
    public T getConteudo() { return conteudo; }
}

Caixa<String> c = new Caixa<>("Olá");
String s = c.getConteudo();   // sem cast

Só funcionam com tipos de referência: Caixa<Integer>, não Caixa<int>.

Strings

String s = "Hello World";
int n = s.length();               // 11
String sub = s.substring(0, 5);   // "Hello"
String r = s.replace("World", "Java");
String[] partes = "Ana,Bruno".split(",");
boolean tem = s.contains("World");

StringBuilder sb = new StringBuilder();
sb.append("Olá ").append("mundo");
String texto = sb.toString();     // "Olá mundo"
  • As String são imutáveis: cada operação devolve uma nova, a original nunca muda.
  • Compara com equals(), nunca com ==.
  • Em ciclos longos, StringBuilder evita criar uma String nova a cada volta.
Bloco 6 · Coleções

Escolher a estrutura certa

Qual coleção escolher

Preciso de... Usa
Sequência com acesso por posição ArrayList
Valores sem repetição HashSet
Valores sem repetição, ordenados TreeSet
Procurar por chave HashMap
Chaves ordenadas TreeMap

Programa contra a interface: List<String> x = new ArrayList<>();.

List

List<String> nomes = new ArrayList<>();
nomes.add("Ana");
nomes.add("Bruno");
String primeiro = nomes.get(0);
nomes.remove("Bruno");

for (String n : nomes) { System.out.println(n); }

List<String> fixos = List.of("a", "b");   // imutável

Map

Map<String, Integer> idades = new HashMap<>();
idades.put("Ana", 25);
idades.put("Bruno", 30);

int a = idades.getOrDefault("Carla", 0);   // 0

for (Map.Entry<String, Integer> e : idades.entrySet()) {
    System.out.println(e.getKey() + " -> " + e.getValue());
}

Set e ordenação

Set<String> unicos = new HashSet<>();
unicos.add("Ana");
unicos.add("Ana");        // ignorado
System.out.println(unicos.size());   // 1

turma.sort(Comparator.comparing(Aluno::nome));
turma.sort(Comparator.comparingInt(Aluno::nota).reversed());
  • Comparable: ordem natural, dentro da classe.
  • Comparator: ordem alternativa, fora da classe.

Streams

List<Integer> n = List.of(1, 2, 3, 4, 5, 6);

List<Integer> pares = n.stream()
    .filter(x -> x % 2 == 0)
    .collect(Collectors.toList());

int soma = n.stream().mapToInt(Integer::intValue).sum();

String s = List.of("ana", "bruno").stream()
    .map(String::toUpperCase)
    .collect(Collectors.joining(", "));
Bloco 7 · Exceções

Tratar o que corre mal

Hierarquia de exceções

Throwable
├── Error
└── Exception
    ├── RuntimeException   (unchecked)
    │   ├── NullPointerException
    │   └── ArithmeticException
    └── IOException        (checked)
  • Checked: o compilador obriga a tratar ou declarar.
  • Unchecked: tratar é opcional.

try, catch, finally

try {
    System.out.println(10 / 0);
} catch (ArithmeticException e) {
    System.out.println("Erro: " + e.getMessage());
} catch (Exception e) {
    System.out.println("Outro erro");
} finally {
    System.out.println("Sempre executa");
}

try (Scanner sc = new Scanner(new File("dados.txt"))) {
    while (sc.hasNextLine()) { System.out.println(sc.nextLine()); }
}

throw, throws e exceções próprias

public class SaldoInsuficienteException extends Exception {
    public SaldoInsuficienteException(String msg) { super(msg); }
}

public void sacar(double valor) throws SaldoInsuficienteException {
    if (valor > saldo) {
        throw new SaldoInsuficienteException("Saldo: " + saldo);
    }
    saldo -= valor;
}
Bloco 8 · Ficheiros e bases de dados

Persistir dados

Ler e escrever ficheiros

Path p = Path.of("dados.txt");

String texto = Files.readString(p);
List<String> linhas = Files.readAllLines(p);

Files.writeString(p, "Olá\n");
Files.writeString(p, "Mais\n", StandardOpenOption.APPEND);

try (var s = Files.lines(p)) {
    s.filter(l -> l.contains("erro")).forEach(System.out::println);
}

JDBC: ligar e consultar

String sql = "SELECT id, nome, preco FROM produtos WHERE preco > ?";

try (Connection conn = DriverManager.getConnection(url, user, pwd);
     PreparedStatement st = conn.prepareStatement(sql)) {
    st.setDouble(1, 10.0);
    try (ResultSet rs = st.executeQuery()) {
        while (rs.next()) {
            System.out.println(rs.getString("nome"));
        }
    }
}

INSERT e SQL injection

String sql = "INSERT INTO produtos (nome, preco) VALUES (?, ?)";
try (PreparedStatement st = conn.prepareStatement(sql)) {
    st.setString(1, "Caneta");
    st.setDouble(2, 1.50);
    st.executeUpdate();
}

Nunca concatenar texto do utilizador em SQL:

"SELECT * FROM users WHERE name = '" + nome + "'"   // NUNCA

DAO e transações

public record Produto(int id, String nome, double preco) { }

public class ProdutoDAO {
    public List<Produto> listar() throws SQLException { /* ... */ }
    public void inserir(Produto p) throws SQLException { /* ... */ }
}
conn.setAutoCommit(false);
try {
    // várias operações
    conn.commit();
} catch (SQLException e) {
    conn.rollback();
    throw e;
}
Bloco 9 · Testes e qualidade

Provar, depurar e documentar

Testes com JUnit 5

class CalculadoraTest {
    private Calculadora c;

    @BeforeEach
    void preparar() { c = new Calculadora(); }

    @Test
    void somaSimples() { assertEquals(5, c.somar(2, 3)); }

    @Test
    void divisaoPorZero() {
        assertThrows(ArithmeticException.class, () -> c.dividir(10, 0));
    }
}

Depurar com método

  1. Reproduzir o erro.
  2. Isolar o caso mais pequeno que falha.
  3. Hipótese confirmada com o depurador ou um teste.
  4. Corrigir a causa, não o sintoma.
  5. Escrever um teste para que não volte.

Lê a stack trace de cima para baixo e procura a primeira linha de código teu.

Convenções e princípios

  • Classes: PascalCase. Métodos e variáveis: camelCase.
  • Constantes: UPPER_SNAKE_CASE. Pacotes: minúsculas.
  • Booleanos: isAtivo, hasPermissao.
  • Encapsular, composição antes de herança, responsabilidade única.
  • DRY: não repetir. YAGNI: não construir o que ninguém pediu.

Documentar: Javadoc, guião e manual

/**
 * Calcula o preço final com IVA.
 * @param preco preço sem IVA
 * @param taxa  taxa de IVA, por exemplo 0.23
 * @return preço com IVA
 */
Documento Para quem
Guião técnico Programadores
Manual de utilizador Quem usa a aplicação

Erros comuns em Java

Erro Correção
== em String equals()
nextInt() e depois nextLine() Se leres texto depois de um número, lê sempre com nextLine() e Integer.parseInt
i <= v.length i < v.length
NullPointerException Inicializar ou usar Optional
Alterar lista no for removeIf
equals sem hashCode Sobrepor ambos
SQL concatenado PreparedStatement

UC00619 · resumo

  • Planear antes de programar: algoritmos, requisitos, diagrama de classes.
  • Java compila para bytecode e corre na JVM.
  • POO: encapsulamento, herança, polimorfismo, interfaces, genéricos.
  • Coleções (List, Set, Map) e streams.
  • Exceções com try-catch e try-with-resources.
  • Ficheiros com Files; JDBC sempre com PreparedStatement.
  • Testes com JUnit 5 e depuração com método.
  • Documentar com Javadoc, guião técnico e manual de utilizador.

NOTAS DO PROFESSOR - enfatizar: Java existe há cerca de 30 anos e continua a ser dos mais pedidos no mercado. - erro comum/pergunta: se corre em qualquer sistema, porque se instala o JDK em cada máquina? Porque cada sistema precisa da sua JVM. - exemplo/analogia: o bytecode é um guião universal; a JVM é o ator local que o interpreta.

NOTAS DO PROFESSOR - enfatizar: Distinguir os três tipos de erro, porque cada um se procura de forma diferente. - erro comum/pergunta: achar que um programa que compila está correto. - exemplo/analogia: dividir por zero compila sem problema e só falha ao executar.

NOTAS DO PROFESSOR - enfatizar: Variáveis de objeto guardam referências, não os objetos. - erro comum/pergunta: o que acontece a `outro` se `nome` deixar de apontar para o objeto? Continua a apontar. - exemplo/analogia: a referência é a morada, o objeto é a casa; duas moradas iguais levam à mesma casa.

NOTAS DO PROFESSOR - enfatizar: O pensamento computacional vem antes de qualquer linha de código. - erro comum/pergunta: abrir o IDE e começar a escrever sem ter decomposto o problema. - exemplo/analogia: calcular a média de uma turma decompõe-se em ler, somar, dividir e classificar.

NOTAS DO PROFESSOR - enfatizar: Todo o programa Java combina apenas estas três estruturas. - erro comum/pergunta: que estrutura usar para pedir uma password até estar certa? Repetição. - exemplo/analogia: uma receita de cozinha tem sequência, escolhas ("se a massa estiver seca") e repetições ("mexer até ligar").

NOTAS DO PROFESSOR - enfatizar: O teste de mesa executa o algoritmo à mão antes de o programar. - erro comum/pergunta: não testar com valores onde o maior é o primeiro, o do meio e o último. - exemplo/analogia: repetir o teste com 9, 4, 7 e com 4, 7, 9 confirma que o algoritmo é geral.

NOTAS DO PROFESSOR - enfatizar: Duas ideias: o ciclo pára cedo (`return`) e o limite reduz o trabalho. - erro comum/pergunta: porque é que 1 e 0 não são primos? A condição `n < 2` trata esse caso. - exemplo/analogia: para 25, testa 2, 3, 4 e 5; no 5 encontra o divisor e termina.

NOTAS DO PROFESSOR - enfatizar: Cada fase tem um produto concreto, não é apenas uma etapa de trabalho. - erro comum/pergunta: tratar os testes como uma fase final em vez de os fazer ao longo do trabalho. - exemplo/analogia: o produto do desenho é o diagrama de classes e o esquema da base de dados.

NOTAS DO PROFESSOR - enfatizar: Não há metodologia melhor em abstrato: depende de os requisitos serem estáveis ou não. - erro comum/pergunta: quando faz sentido a cascata? Com requisitos fechados e conhecidos de antemão. - exemplo/analogia: a cascata é construir uma ponte por plano; o ágil é afinar um restaurante com o feedback dos clientes.

NOTAS DO PROFESSOR - enfatizar: A história obriga a dizer para quê, não apenas o quê. - erro comum/pergunta: requisitos vagos como "deve ser rápido", impossíveis de testar. - exemplo/analogia: "a listagem abre em menos de 2 segundos com 1000 livros" é um requisito testável.

NOTAS DO PROFESSOR - enfatizar: Ordenar por dependência e por risco: o modelo vem antes da persistência. - erro comum/pergunta: que etapa pode ser feita em paralelo com outra? A interface, depois de acordado o modelo. - exemplo/analogia: estimar horas por etapa dá uma noção do prazo e permite renegociar cedo.

NOTAS DO PROFESSOR - enfatizar: Três compartimentos por classe: nome, atributos, métodos. - erro comum/pergunta: desenhar o diagrama depois do código, só para cumprir a entrega. - exemplo/analogia: ler o diagrama como frases, "um leitor tem muitos empréstimos".

NOTAS DO PROFESSOR - enfatizar: A interface desenha-se em papel ou em texto antes de se programar. - erro comum/pergunta: o que acontece se o utilizador escrever "dois" no menu? Mensagem de opção inválida e nova pergunta. - exemplo/analogia: escrever primeiro as mensagens (`Esse livro já está emprestado. Escolhe outro.`) para serem consistentes.

NOTAS DO PROFESSOR - enfatizar: As normas são requisitos do projeto, não burocracia. - erro comum/pergunta: uma aplicação de biblioteca guarda NIF dos leitores. Precisa mesmo? Aplicar o princípio do mínimo necessário. - exemplo/analogia: antes de usar uma biblioteca num produto comercial, confirmar a licença.

NOTAS DO PROFESSOR - enfatizar: Versões LTS são as que as empresas usam em produção. - erro comum/pergunta: "comando não encontrado" por o JDK não estar no `PATH`. - exemplo/analogia: o Maven usa `JAVA_HOME` para escolher o Java com que compila.

NOTAS DO PROFESSOR - enfatizar: Saber também trabalhar com um editor simples e o terminal, que é o que há em servidores. - erro comum/pergunta: o que é refatorar? Mudar a estrutura sem mudar o comportamento. - exemplo/analogia: renomear um método em todo o projeto com um atalho, em vez de procurar à mão.

NOTAS DO PROFESSOR - enfatizar: Toda a aplicação Java começa em `public static void main`. - erro comum/pergunta: ficheiro `helloworld.java` para a classe `HelloWorld`; as maiúsculas contam. - exemplo/analogia: `java HelloWorld.java` compila e corre num só passo, útil para scripts.

NOTAS DO PROFESSOR - enfatizar: Cada palavra tem uma razão; a JVM tem de conseguir chamar o método sem criar objetos. - erro comum/pergunta: o que acontece se tirarmos o `static`? A JVM não encontra o ponto de entrada. - exemplo/analogia: passar o nome do utilizador como argumento em vez de o pedir.

NOTAS DO PROFESSOR - enfatizar: Depurar é mais rápido e mais fiável do que espalhar `println`. - erro comum/pergunta: corrigir o sintoma sem descobrir a causa. - exemplo/analogia: parar no início de um ciclo e acompanhar o valor de `soma` a cada volta.

NOTAS DO PROFESSOR - enfatizar: Ler a mensagem inteira é meio caminho andado. - erro comum/pergunta: porque devemos recompilar a seguir à primeira correção? Porque o compilador analisa por fases: primeiro a sintaxe, depois os tipos. - exemplo/analogia: um revisor que só começa a verificar os factos depois de o texto estar pontuado.

NOTAS DO PROFESSOR - enfatizar: Ler a assinatura diz o que entra, o que sai e o que pode correr mal. - erro comum/pergunta: porque se cria `new ArrayList<>(List.of(...))`? `List.of` é imutável e `removeIf` lançaria `UnsupportedOperationException`. - exemplo/analogia: procurar um método novo na API antes de pedir a ajuda de um colega.

NOTAS DO PROFESSOR - enfatizar: A estrutura standard permite que qualquer pessoa ou ferramenta percebam o projeto. - erro comum/pergunta: colocar testes em `src/main`. - exemplo/analogia: abrir o projeto de um colega e saber logo onde está cada coisa.

NOTAS DO PROFESSOR - enfatizar: O Maven protege a equipa de entregar código partido. - erro comum/pergunta: o que faz `mvn clean`? Apaga a pasta `target/` antes de recompilar. - exemplo/analogia: acrescentar o JUnit ao `pom.xml` e deixar o Maven descarregá-lo.

NOTAS DO PROFESSOR - enfatizar: Oito tipos primitivos, de tamanho fixo. - erro comum/pergunta: escrever `8_000_000_000` sem o `L` final; deixa de caber num `int`. - exemplo/analogia: `long populacao = 8_000_000_000L;`.

NOTAS DO PROFESSOR - enfatizar: Para texto usa-se sempre `equals`. - erro comum/pergunta: comparar `String` com `==`; pode dar certo por acaso e falhar depois. - exemplo/analogia: `a != 0 && 10 / a > 1` nunca divide por zero.

NOTAS DO PROFESSOR - enfatizar: Para um tipo menor é preciso cast, e pode perder-se informação. - erro comum/pergunta: `(int) 3.99` dá 3 ou 4? Dá 3, o cast corta e não arredonda. - exemplo/analogia: ler uma idade em texto e convertê-la para `int` antes de somar.

NOTAS DO PROFESSOR - enfatizar: O `switch` com `->` não precisa de `break` e devolve um valor. - erro comum/pergunta: esquecer o `break` no `switch` tradicional e executar vários casos. - exemplo/analogia: transformar um número de dia da semana num texto.

NOTAS DO PROFESSOR - enfatizar: Escolher o ciclo certo pelo que se sabe sobre as repetições. - erro comum/pergunta: `i <= v.length` num array. - exemplo/analogia: pedir um valor e validar com `do-while`.

NOTAS DO PROFESSOR - enfatizar: Aceder a `v[5]` num array de 5 elementos lança `ArrayIndexOutOfBoundsException`. - erro comum/pergunta: qual o último índice de um array com 10 elementos? 9. - exemplo/analogia: uma tabela de notas é um array bidimensional (aluno por teste).

NOTAS DO PROFESSOR - enfatizar: Um método faz uma só coisa e tem um nome que a diz. - erro comum/pergunta: achar que um método consegue trocar duas variáveis `int` do chamador. - exemplo/analogia: `somar(2, 3)` escolhe a versão de `int`; `somar(2.5, 3.5)` a de `double`.

NOTAS DO PROFESSOR - enfatizar: A classe é o molde; o objeto é a instância. - erro comum/pergunta: para que serve o `this`? Distingue o atributo do parâmetro com o mesmo nome. - exemplo/analogia: a classe é a planta da casa; os objetos são as casas construídas a partir dela.

NOTAS DO PROFESSOR - enfatizar: Atributos privados, acesso controlado: o setter valida. - erro comum/pergunta: atributos `public`, que deixam qualquer código deixar o objeto num estado inválido. - exemplo/analogia: a idade nunca pode ficar negativa porque só se altera pelo setter.

NOTAS DO PROFESSOR - enfatizar: A inicialização fica num só construtor; os outros reencaminham. - erro comum/pergunta: usar `this` dentro de um método `static`. - exemplo/analogia: um contador `static` que numera os objetos criados.

NOTAS DO PROFESSOR - enfatizar: Distinguir "é um" de "tem um". - erro comum/pergunta: uma `Turma` e os seus `Aluno`s são agregação ou composição? Agregação, o aluno existe sem a turma. - exemplo/analogia: `Casa` e `Divisao` é composição; se a casa desaparece, as divisões também.

NOTAS DO PROFESSOR - enfatizar: Em execução, os objetos relacionam-se através de referências. - erro comum/pergunta: tentar um muitos-para-muitos direto, sem classe intermédia. - exemplo/analogia: a inscrição guarda a data e a nota, que não pertencem nem ao aluno nem à disciplina.

NOTAS DO PROFESSOR - enfatizar: A herança partilha comportamento e permite evoluir sem alterar a classe base. - erro comum/pergunta: herdar só para reutilizar código, sem haver relação "é um". - exemplo/analogia: `Empregado` é uma `Pessoa`; já um `Carro` não deve herdar de `Motor`.

NOTAS DO PROFESSOR - enfatizar: O método executado é o da classe real do objeto, não o do tipo da variável. - erro comum/pergunta: acrescentar um `Triangulo` obriga a mexer no ciclo? Não. - exemplo/analogia: pedir "abre" a uma porta, a uma janela e a um frasco: cada um abre à sua maneira.

NOTAS DO PROFESSOR - enfatizar: Uma interface é um contrato: diz o que se pode fazer, não como. - erro comum/pergunta: tentar fazer `new` de uma classe abstrata ou de uma interface. - exemplo/analogia: `Comparable` é cumprido por `String`, `Integer` e pelas tuas classes.

NOTAS DO PROFESSOR - enfatizar: Menos código repetitivo e mais segurança de tipos. - erro comum/pergunta: porque é melhor um `enum` do que um `int` para o estado? O compilador recusa valores inválidos. - exemplo/analogia: um `record Aluno(String nome, int nota)` em duas linhas.

NOTAS DO PROFESSOR - enfatizar: Os genéricos dão segurança de tipos em compilação. - erro comum/pergunta: usar `List` sem tipo e receber `Object`, obrigando a casts. - exemplo/analogia: `List<String>` recusa à partida um `Integer`.

NOTAS DO PROFESSOR - enfatizar: `s.replace(...)` sozinho não altera `s`; é preciso guardar o resultado. - erro comum/pergunta: o que vale `s` depois de `s.toUpperCase();` sem atribuição? Continua igual. - exemplo/analogia: uma `String` é como texto impresso; para mudar, imprime-se outra folha.

NOTAS DO PROFESSOR - enfatizar: A escolha depende do acesso que vais fazer, não do hábito. - erro comum/pergunta: que coleção para contar quantas vezes cada palavra aparece? Um `Map`. - exemplo/analogia: IDs únicos de utilizadores guardam-se num `Set`.

NOTAS DO PROFESSOR - enfatizar: Lista ordenada que aceita duplicados e cresce sozinha. - erro comum/pergunta: alterar uma `List.of(...)` e apanhar `UnsupportedOperationException`. - exemplo/analogia: carrinho de compras como lista de produtos.

NOTAS DO PROFESSOR - enfatizar: Pares chave e valor; as chaves são únicas. - erro comum/pergunta: `get` numa chave inexistente devolve `null`; usar `getOrDefault`. - exemplo/analogia: `merge(palavra, 1, Integer::sum)` conta ocorrências numa só linha.

NOTAS DO PROFESSOR - enfatizar: Um `Set` elimina repetições; o `Comparator` ordena sem alterar a classe. - erro comum/pergunta: como ordenar por nota decrescente e depois por nome? Encadear `thenComparing`. - exemplo/analogia: classificação de uma turma por nota, com desempate alfabético.

NOTAS DO PROFESSOR - enfatizar: Um stream não altera a coleção original e só corre quando chega a operação terminal. - erro comum/pergunta: esperar que `filter` modifique a lista original. - exemplo/analogia: da lista de produtos, os nomes dos que custam menos de 2 euros.

NOTAS DO PROFESSOR - enfatizar: Uma exceção é um objeto que sobe a cadeia de chamadas até encontrar um `catch`. - erro comum/pergunta: porque não se trata um `Error`? São falhas graves da JVM, sem recuperação possível. - exemplo/analogia: `IOException` ao abrir um ficheiro que não existe.

NOTAS DO PROFESSOR - enfatizar: O `catch` específico vem antes do geral; `try-with-resources` fecha o recurso sozinho. - erro comum/pergunta: `catch (Exception e) { }` vazio, que esconde os erros. - exemplo/analogia: ler um número e pedir de novo se o utilizador escrever texto.

NOTAS DO PROFESSOR - enfatizar: `throw` lança; `throws` avisa quem chama. - erro comum/pergunta: quando criar uma exceção própria? Quando o erro tem significado no domínio. - exemplo/analogia: o levantamento recusado deixa o saldo intacto e o chamador decide o que fazer.

NOTAS DO PROFESSOR - enfatizar: `Files` e `Path` são a forma moderna; `Files.lines` lê sem carregar tudo em memória. - erro comum/pergunta: esquecer que estes métodos lançam `IOException`. - exemplo/analogia: guardar produtos num CSV com `;` como separador e relê-los.

NOTAS DO PROFESSOR - enfatizar: Os recursos fecham-se pela ordem inversa à de abertura, com `try-with-resources`. - erro comum/pergunta: palavra-passe escrita no código; ler de variável de ambiente. - exemplo/analogia: SQLite não precisa de servidor, com URL `jdbc:sqlite:loja.db`.

NOTAS DO PROFESSOR - enfatizar: Com `PreparedStatement`, o valor nunca é interpretado como comando. - erro comum/pergunta: o que devolve a versão concatenada se `nome` for `' OR '1'='1`? Todos os utilizadores. - exemplo/analogia: um formulário de login vulnerável deixa entrar sem palavra-passe.

NOTAS DO PROFESSOR - enfatizar: O DAO isola o acesso a dados; a transação garante tudo ou nada. - erro comum/pergunta: SQL espalhado pela interface de utilizador. - exemplo/analogia: transferir dinheiro debita uma conta e credita outra na mesma transação.

NOTAS DO PROFESSOR - enfatizar: Preparar, Agir, Verificar; testar o normal, os limites e os erros. - erro comum/pergunta: um teste que verifica várias coisas e falha por muitas razões. - exemplo/analogia: `Desconto.aplicar(100.0)` com a condição `>` em vez de `>=` falha no teste do limite.

NOTAS DO PROFESSOR - enfatizar: Cada defeito corrigido ganha um teste. - erro comum/pergunta: porque não basta corrigir e seguir em frente? Sem teste, o defeito pode regressar. - exemplo/analogia: `NullPointerException` na linha 42; a stack trace diz qual a variável nula.

NOTAS DO PROFESSOR - enfatizar: As convenções poupam tempo de leitura à equipa. - erro comum/pergunta: nomes como `calc2` ou `x1`. - exemplo/analogia: extrair a taxa de IVA para uma constante `TAXA_IVA`.

NOTAS DO PROFESSOR - enfatizar: Os comentários explicam o porquê; o código mostra o quê. - erro comum/pergunta: o que deve ter o README? Requisitos, como compilar, como executar e como testar. - exemplo/analogia: um manual com um exemplo de utilização por cada opção do menu.

NOTAS DO PROFESSOR - enfatizar: Quase todos os erros iniciais cabem nesta tabela. - erro comum/pergunta: qual destes já cometeram? Pedir exemplos reais. - exemplo/analogia: remover elementos de uma lista dentro de um `for` mostra `ConcurrentModificationException`.

NOTAS DO PROFESSOR - enfatizar que testar, depurar e documentar fazem parte do trabalho, não são extras - pergunta: que parte do ciclo, do planeamento à entrega, ainda parece menos segura? - exemplo: o mini-projeto percorre todo o ciclo numa aplicação com base de dados