Jazyk Java
- Objektově orientovaný jazyk
- Syntaxe vychází z C/C++
- Na rozdíl od C/C++ máme:
- Automatická správa paměti
- Kontrola mezí polí
- Pouze bezpečné prvky jazyka
- Jiný objektový systém
- Portabilita (Přenostitelnost)
- Systém výjimek
- Více implementací (Oracle, OpenJDK, …)
- Bohatá standardní knihovna a mnoho dalších knihoven
- Nová verze dvakrát ročně (od Java 10)
Platforma Java
- Sada mnoha nástrojů umožňující vývoj (nejen) v Javě
- Dostupné pro různorodý hardware (portabilita)
- JVM - Java Virtual Machine
- JDK - Java Development Kit
- JRE - Java Runtime Environment
- Podporuje mnoho dalších jazyků: Scala, Groovy, Clojure, Kotlin, …
- JavaCard (applety), Java ME (malá zařízení), Java SE, Jakarta EE (podnikové systémy)
IDE (Integrated development environment)
- IntelliJ Idea (doporučeno)
- Apache Netbeans
- Eclipse
- …
IDE nabízí spoustu možností, jak si usnadnit práci. Využívejte toho!
- Formátování
- Generování kódu
- Refactoring
- Debugger
- Profiler
- Naštěpávač
- Rady
- Verzování
- Pluginy
Základní konstrukce jazyka Java
V této kapitole jsou popsány základní konstrukce Jazyka Java, které je nutné bezpodmínečně znát.
Konvence
Veškerý odevzdaný kód musí dodržovat konvence, jinak bude vrácen k přepracování. Budeme používat Google konvence.
Čitelnost kódu je velmi důležitá vlastnost.
Příkazy a bloky
Příkazy ukončujeme středníkem, např.
System.out.println("Hello World!");
Výše uvedený příkaz vypíše na obrazovku Hello World!
Bloky jsou uzavřeny do složených závorek, např.
{
System.out.println("Hello World!");
System.out.println("How are you?");
System.out.println("BUM!");
}
Primitivní datové typy
boolean
- pravdivostní hodnoty
- literály
true
afalse
char
- znaky (unicode)
- literály v
''
- escape sequence začínaji \, např.
'\n'
,'\t'
,'\\'
, … - unicode znaky
\uXXXX
, kdeX
je šestnáctková číslice
byte
- celá čísla od -128 do 127 (27)
- nemá literály (přetypování)
short
- celá čísla od -32 768 do 32 767 (215)
- nemá literály (přetypování)
int
- celá čísla od -2 147 483 648 do 2 147 483 647 (231)
- více možnýh soustav (
Y
je libovolná číslice dané soustavy):- dvojková - tvar
0bYYY...
- osmičková - tvar
0YYY...
- desítková - klasika, nesmí začínat 0
- šestnáctková - tvar
0xYYYY
- dvojková - tvar
- literály jsou prostě celá čísla v daném rozsahu
long
- celá čísla od -9 223 372 036 854 775 808 do 9 223 372 036 854 775 807 (263)
- literály končí znakem L, např
123L
float
- reálná čísla s přesností na 6 číslic
- literály končí znakem F, např
0.25F
double
- reálná čísla s přesností na 15 číslic
- literály:
- prostě desetinná čísla v daném rozsahu
- celé číslo končící znakem D, např
123D
- číslo v exponentovém/vědeckém tvaru, např
3.14159e5
pro 3.14159 ⋅ 105
- navíc
NaN
,POSITIVE_INFINITY
,NEGATIVE_INFINITY
Přetypování
Implicitně ze specifičtějšího typu na obecnější, tj např lze uložit
int
dodouble
proměnné nebochar
doint
proměnné. Naopak implicitně nelze.Explicitně když víme něco víc než překladač.
Syntaxe:
(novyTyp) hodnota
.Např
int a = (int) funkceBezneVracejiciDouble(arg1, arg2)
když vím, že zronva s těmito argumenty moje funkce vrátí celé číslo.
Typické použítí je přesné dělení dvou celých čísel operátorem
/
(viz dále) nebo useknutí desetinné části zdouble
hodnoty (pozor na velikost).Literály i práce s typy
byte
ashort
vyžadují přetypování, neboť např(byte) a + (byte) b
je typuint
. Chceme-li zasebyte
, pak musíme použít(byte)((byte) a + (byte) b)
Operátory
Priorita odshora dolů.
A je-li zle tak: “Když nevíš, dej tam závorky.” Tj (skoro) vše se dá uzávorkovat tak, aby člověk určil, v jakém pořadí se mají části výrazu vyhodnocovat.
Unární
Postfixové
++
--
Prefixové
++
--
+
-
!
- negace~
- bitový doplňěk
Binární
Multiplikativní
*
/
%
- zbytek po celočísleném dělení
Aditivní
+
-
Posun
<<
- bitový posun doleva (vyplňuje 0)>>
- bitový posun doprava (vyplňuje znaménkovým bitem)>>>
- bitový posun doprava (vyplňuje 0)
Relační
<
>
<=
>=
instanceof
Relační - (ne)rovnost
==
!=
Bitové
&
- bitové AND^
- bitové XOR|
- bitové OR
Logické
&&
||
Ternární
? :
Přiřazení
=
+=
-=
*=
/=
%=
&=
^=
|=
<<=
>>=
>>>=
O něco úplnější tabulka s operátory v Javě.
Proměnné
Jazyk Java je staticky typovaný programovací jazyk. Od verze 10 umožňuje použít tzv. typovou inferenci (odvození typu).
var secretNumber = 10;
nebo
var secretPassword = "topS3cr3t";
Ale pozor, nemůžeme napsat:
var x;
V tomto případě interpret nemá z čeho odvodit typ a volání skončí chybou.
Obecně se proměnné deklarují ve tvaru
// Deklarace proměnné
type variableName;
// Deklarace proměnné s výchozí hodnotou
type variableName = default_value;
Příklady deklarací
int number = 123;
double doubleNumber = 2.88;
String greeting = "Hello";
Konstanty
Při programovaná se stává že hodnotu potřebujeme nastavit pouze 1 a
pak zněmožnit její přepsání. Toho docílíme pomocí klíčového slova final
.
final double PI = 3.14;
Podmíněný příkaz
Podmíněné příkazy vypadají podobně jako v C:
if (condition) {
statements;
}
if (condition) {
statements;
} else {
statements;
}
if (condition) {
statements;
} else if (condition) {
statements;
} else {
statements;
}
V javě stejně jako v C máme k dispozici i ternární operátor:
x = (y == 27) ? 10 : 20;
Switch
V Javě lze od verze 16 switch použít jako příkaz i jako výraz a od verze 17 možnost pattern matchingu ve switch příkazech/výrazech.
Switch jako příkaz
switch (condition) {
case option:
statements;
/* falls through */
case 1:
statements;
break;
case 2:
statements;
break;
default:
statements;
break;
}
Switch jako výraz
switch (condition) {
case label_1, label_2, label_3 -> value_1;
.
.
.
case label_n -> value_m;
default -> default_value;
}
// Příklad
var monthNumber = 2;
var numberOfDays = switch(month) {
case 1, 3, 5, 7, 8, 10, 12 -> 31;
case 2 -> 28;
case 4, 6, 9, 11 -> 30;
default -> 0;
};
Switch pomoci yield
switch (condition) {
case label_1:
case label_2:
case label_3:
statements;
yield value_1;
.
.
.
case label_n:
statements;
yield value_m;
default:
statements;
yield default_value;
}
// Příklad
var numberOfDays = switch(month) {
case 1, 3, 5, 7, 8, 10, 12 -> 31 {
S
case 2 -> 28;
case 4, 6, 9, 11 -> 30;
default -> 0;
};
Switch výrazy musí být vyčerpávající, tedy jednotlivé větve musí zahrnout každý
možný případ. Lze vyřešit default větví. U switch přes malé enumy (výčtové typy, uvidíme později)
lze vypsat všechny možnosti a default vynechat - kompilátor si jej doplní.
Navíc ze switch výrazů nelze utéct pomocí break;
či continue;
,
protože musí vrátit hodnotu.
Pro switch příkazy tato omezení neplatí.
Cykly
U všech cyklů fungují příkazy break;
a continue;
. Příkaz break;
cyklus ukončí, continue;
přejde k další iteraci.
For cyklus
for (initialization; condition; update) {
statements;
}
While cyklus
while (condition) {
statements;
}
Do-while cyklus
do {
statements;
} while (condition);
Metody (funkce)
return-type name (type1 arg1, type2 arg2, ..., typen argn) {
statements;
return return-value;
}
Pokud metoda nemá nic vracet, její návratový typ return-type
je void
(bude se hodit v úkolech níže).
Úkoly
Úkoly mi neposílejte, budou zkontrolovány na dalším semináři.
primes
beroucí jeden argument typu int,
která vypíše všechna prvočísla menší než zadaný argument
oddělená čárkou a mezerou (ve standardním pořadí). Za posledním
vypsaným číslem bude taktéž čárka a mezera.
static void primes(int upperBound) {
// Vase reseni
}
multiply
ob beroucí dva argumenty typu int vracející
jejich součin, ale používající z aritmetických operací pouze sčítání
a odčítání. Mohou se hodit funkce z knihovny Math (vizte dokumentaci).
static int multiply(int left, int right) {
// Vase reseni
}
multiply(5, 6); // -> 30
nameNumber
vracející pro zadané číslo v rozsahu 1 až 10
jemu odpovídající české slovo a pro čísla mimo zadaný rozsah vrátí
slovo “neznám”.
nameNumber(3); // -> "Tři"
printTriangle
která bere délku
strany rovnostranného trojúhelníku a vytiskne jej na obrazovku následovně:
// n = 5
*
**
* *
* *
*****