- program je zkompilovaný do spustitelného souboru, skládá se z nativních procesorových instrukcí, které přímo vykonává procesor a musí být tedy kompilován pro konkrétní architekturu a systém. Mezi tyto jazyky patří například C/C
SQLException ex) { log(ex);
throw ex; // volitelné předání dál
} finally {
cleanup(); // provede se vždy
}
</code>
* try-with-resources (Java 7+) – vše, co implementuje AutoCloseable, se zavře automaticky:
try (BufferedReader br = Files.newBufferedReader(Path.of("data.txt"))) {
return br.readLine();
}
==== Vlastní výjimky ====
public class DataFormatException extends Exception { // checked
public DataFormatException() {}
public DataFormatException(String msg) { super(msg); }
public DataFormatException(String msg, Throwable cause) {
super(msg, cause);
}
}
* Kdy se hodí? Když stávající výjimky nedostačují a potřebuješ popsat specifickou situaci.
* Rozhodni se, zda má být checked (nutí volající k ošetření) nebo unchecked (dědí z RuntimeException).
==== Best practices ====
* Vyhazuj co nejkonkrétnější výjimky, ať je volající může smysluplně řešit.
* Nezachytávej zbytečně obecné Exception/Throwable – skrýváš tím chyby.
* Vždy uvolňuj prostředky (soubor, socket…) v finally nebo ještě lépe v try-with-resources.
* Přidávej smysluplné chybové zprávy, aby bylo z logu jasné *proč* se výjimka stala.
===== Práce se soubory (java.io) =====
==== Klíčové třídy ====
* File – abstraktní reprezentace cesty; umí zjišťovat existenci, práva, velikost a vytvářet adresáře/základní soubory.
* InputStream / OutputStream – bajtové proudy (binární data).
* Dekorátory: ''Buffered*'' (buffer), ''Data*'' (primitiva), ''Object*'' (serializace), ''GZIP*'' (komprese)…
* **''Reader'' / ''Writer''** – znakové proudy (text, kódování).
* Typicky ''BufferedReader'', ''InputStreamReader'' (převod bajt→znak), ''FileWriter'' atd.
* **''RandomAccessFile''** – čtení/zápis s libovolným posuvem uvnitř souboru.
* **Rozhraní ''Closeable'' / ''Flushable'' / ''Serializable''** – sjednocují zavírání, flush a serializaci.
==== Vytvoření a použití proudů ====
try (InputStream in = new FileInputStream("logo.png");
OutputStream out = new FileOutputStream("copy.png")) {
byte[] buf = new byte[8192];
int n;
while ((n = in.read(buf)) != -1) {
out.write(buf, 0, n);
}
} // oba proudy se zavřou automaticky (try-with-resources)
==== Otevření jednoduchého textového souboru (java.io) ====
Nejčastější (a dodnes plně dostačující) kombinací je dvojice ``FileReader`` + ``BufferedReader``:
try (BufferedReader br =
new BufferedReader(new FileReader("soubor.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} // try-with-resources zajistí zavření souboru
* ``FileReader`` čte znaky (automaticky použije defaultní kódování platformy, nebo explicitně zadej např. ``StandardCharsets.UTF_8``). :contentReference[oaicite:0]{index=0}
* ``BufferedReader`` obalí čtení do větších bloků → méně systémových volání, vyšší výkon. :contentReference[oaicite:1]{index=1}
* Konstrukce try-with-resources (Java 7+) zavře reader i v případě výjimky. :contentReference[oaicite:2]{index=2}
==== Textové vs. binární ====
* Text → Reader/Writer, nutné správné kódování (UTF-8 od JDK 18 default).
* Binární → InputStream/OutputStream; rychlejší, ale nečitelné pro člověka.
==== Serializace objektů ====
try (ObjectOutputStream oos =
new ObjectOutputStream(new FileOutputStream("state.bin"))) {
oos.writeObject(gameState);
}
* Třída musí implementovat Serializable.
* Pozor na kompatibilitu verzí tříd (pole serialVersionUID).
==== Best practices ====
* Vždy používej try-with-resources – žádné zapomenuté close().
* Bufruj I/O (Buffered*) kvůli výkonu.
* Nezachytávej holou Exception; loguj a přeposílej konkrétní typy.
* Při sériové práci se soubory preferuj nové NIO API (java.nio.file.Path) – ošetří limity File a umí asynchronní I/O, ale porozumění java.io je nutný základ.
===== Sokety =====
==== Typy soketů a API ====
| Třída | Protokol | Povaha | Typická použití |
| Socket / ServerSocket | TCP | spojované, spolehlivé | chat, přenos souborů |
| DatagramSocket | UDP | nespojované, best-effort | streaming, hry |
| MulticastSocket | UDP multicast | skupinový přenos | discovery, multicast video |
==== TCP vs. UDP – typy spojení ====
* TCP – potvrzuje doručení a pořadí, detekuje ztráty; pomalejší, ale jistý.
* UDP – žádné záruky, ale nízká latence; sám si případně řešíš potvrzení či opakování paketů.
==== Ukázkový TCP server/klient ====
// === Server ===
try (ServerSocket srv = new ServerSocket(9000)) {
while (true) {
try (Socket s = srv.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream(), true)) {
String line = in.readLine();
out.println("Echo: " + line);
}
}
}
// === Klient ===
try (Socket s = new Socket("localhost", 9000);
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream(), true)) {
out.println("Ahoj světe");
System.out.println(in.readLine());
}
==== Best practices ====
* Porty a backlog: při new ServerSocket(port, backlog) nastavíš frontu nepřijatých spojení.
* Nastav setSoTimeout() → ochrana proti zablokování čtení.
* Na mnoho paralelních spojení použij java.nio.channels + selektory (non-blocking I/O).
* Pro šifrovaný přenos sáhni po SSLSocket / SSLServerSocket nebo moderním klientovi java.net.http.
* Vždy uzavírej soket v try-with-resources nebo finally.
===== 6. Paralelismus =====
Nutné dodržet pravidla synchronizace, aby se zabránilo deadlocku.
Objekty jsou odvozené od třídy Thread, tělo nezávislého výpočtu definujeme v metodě run().
public class Worker extends Thread {
private final int numberOfJobs;
public Worker(int id, int jobs) {
super("Worker " + id);
myID = id;
numberOfJobs = jobs;
stop = false;
System.out.println("Worker id: " + id + " has been created threadID:" + getId());
}
public void run() {
doWork();
}
}
Worker thread = new Worker(1, 10);
thread.start(); //new thread is created
System.out.println("Program continues here");
Pokud nelze použít dědění od Thread implementujeme rozhraní Runnable:
public class WorkerRunnable implements Runnable {
private final int id;
private final int numberOfJobs;
public WorkerRunnable(int id, int jobs) {
this.id = id;
numberOfJobs = jobs;
}
public String getName() {
return "WorkerRunnable " + id;
}
@Override
public void run() { ... }
}
WorkerRunnable worker = new WorkerRunnable(1, 10);
Thread thread = new Thread(worker, worker.getName());
thread.start();
public void run() {
Thread thread = Thread.currentThread();
for (int i = 0; i < numberOfJobs; ++i) {
System.out.println("Thread name: " + thread.getName());
}
}