Seminář 1
Jazyk Java a platforma Java
Jazyk Java
- objektově orientovaný jazyk
- syntax vychází z C/C++, tj. kód vypadá podobně
- ale 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
- dědičnost s maximálně jedním rodičem
- portabilita
- 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)
- vývojová stádia nových vlastností
- zrovna dnes (19.9.2023) vychází nová verze (Java 21).
Platforma Java
- sada mnoha nástrojů umožňující vývoj (nejen) v Javě
- dostupné pro různorodý hardware (portabilita)
- JVM - Java Virtual Machine
- JIT - Just In Time kompilace (Java bytecode)
- JDK - Java Development Kit
- JRE - Java Runtime Environment
- podporuje mnoho dalších jazyků: Scala, Groovy, Clojure, Kotlin, …
- JavaCard, Java ME, Java SE, Jakarta EE
Konvence
Více možností, vyberte si jednu a té se držte. Veškerý odevzdaný kód musí dodržovat konvence, jinak bude vrácen k přepracování.
Čitelnost kódu je velmi důležitá vlastnost.
Vývojá prostředí
JShell
JShell je REPL pro prototypování a experimentování s kódem v Javě. Pro nás je ideální, protože nám z počátku umožní vyhnout se prvkům jazyka souvisejícím s objektově orientovaným programováním (OOP), kterým zatím pravděpodobně nerozumíte. Do OOP budete detailně zasvěceni v jiném kurzu. Zde si to v příštích několika seminářích projdeme jen tak, abychom mohli efektivně používat jazyk Java. Do té doby (a klidně i poté) bude JShell výborným pomocníkem.
REPL spustíme příkazem jshell
v příkazové řádce, případně je (částečně) podporován v některých IDE (vizte níže).
Chcete-li, aby jshell zobrazoval více informací, tak jej spusťte s parametrem -v
, tedy jshell -v
.
(ukázka)
Základní příkazy JShellu
/help
- nápověda/list obj
- vypíše definici obj, při použití bez argumentu vypíše definice všech nadefinovaný objektů./vars
- vypíše nadefinované proměnné a jejich obsah/methods
- vypíše nadefinované “procedury”/“funkce” (metody)/history
- vypíše historii zadaných vstupů- Mnoho dalších užitečných - projděte si
\help
.
(ukázka)
IDE (Integrated development environment)
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
I v IDE můžete mít navíc spuštěný (omezený) JShell pro pokusy.
Základní konstrukce jazyka Java
Teď se podíváme na syntaxi jazyka a základní konstrukce, které musíte ovládat.
Příkazy a bloky
Příkazy ukončujeme středníkem, např.
System.out.println("Ahoj světe!");
je příkaz vypisující typické Ahoj světe!.
Bloky jsou uzavřeny do složených závorek, např.
{
System.out.println("Ahoj světe!");
System.out.println("Jak se máš?");
System.out.println("BUM!");
}
Proměnné
Zatím jsme neřešili typy. Toto lze snadno obejít pomocí automatického odvozování typů lokálních
proměnných. Chcete-li v JShellu vytvořit pojmenovanou proměnnou
použijte var
. REPL si sám doplní typ z kontextu. Například
var oblibeneCislo = 10;
nebo
var tajneHeslo = "topS3cr3t";
Tato vlastnost funguje v Javě obecně pro lokální proměnné (od verze 10).
Ale pozor, nejde napsat jen var x;
, v tomto případě interpret nemá z čeho odvodit typ a volání skončí chybou.
Obecně se proměnné deklarují ve tvaru
typ identifikator [ = vychozi_hodnota];
Základní informace k typům máte níže.
(ukázka)
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;
}
Máme i ternární operátor (a je to výraz):
x = (y == 27) ? 10 : 20;
(ukázka)
Switch
V Javě lze (od verze 16) switch použít jako příkaz i jako výraz.
Switch jako příkaz:
switch (condition) {
case ABC:
statements;
/* falls through */
case DEF:
statements;
break;
case XYZ:
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;
}
Alternativně switch jako výraz s použitím 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;
}
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í.
(ukázka)
Poznámka: V čerstvé Java 21 je možnost pattern matchingu ve switch příkazech/výrazech. Ve starších verzích dostupné v preview.
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;
}
Případně
for (initialization; condition; update);
While cyklus
while (condition) {
statements;
}
Případně
while (condition);
Do-while cyklus
do {
statements;
} while (condition);
(ukázka)
Metody
- “funkce”, “procedury”; terminologie OOP nás čeká příště
return-type name (type1 arg1, type2 arg2, ..., typen argn) {
;
statementsreturn return-value;
}
(ukázka)
Pokud metoda nemá nic vracet, její návratový typ return-type
je void
(bude se hodit v úkolech níže).
Datové typy
- Zjednodušeně množina přípustných hodnot a operace, které s nimi lze provádět.
- Standardní záležitosti, pročtěte si sami, kdyžtak se ptejte.
Primitivní
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
Objektové
Vrátíme se k ním později.
Další
void
- pro definování nic nevracejících funkcí/metod.
Přetypování
Implicitně ze specifičtějšího typu na obecnější, tj. například 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
- Standardní záležitosti, pročtěte si sami, kdyžtak se ptejte.
- Priorita odshora dolů.
- Je-li zle tak: “Když nevíš, dej tam závorky.” Tj. 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í
*
/
- celočíslené vs. desetinné dělení (dle argumentů)%
- 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
- souvisí s objekotvým systémem, vrátíme se k tomu později
Relační - (ne)rovnost
==
!=
Bitové
&
- bitové AND^
- bitové XOR|
- bitové OR
Logické
&&
- AND||
- OR
Ternární
? :
Přiřazení
=
+=
(přičte výsledek vyhodnocení výrazu napravo k aktuální hodnotě místa nalevo a výsledek uloží zpět do místa nalevo) Následující fungují obdobně, jen s odpovídající operací.-=
*=
/=
%=
&=
^=
|=
<<=
>>=
>>>=
O něco úplnější tabulka s operátory v Javě.
Zdroje
- Starší, ale pěkný tutoriál k základům Javy. Neobsahuje novinky po verzi 8!
- Novinky v jednotlivých verzích Javy od 9.
- Popis odvozování typů lokálních proměnných, tj. používání
var
. - Konvence k používání
var
. - Popis výrazu
switch
. - JShell tutoriál.
- IntelliJ IDEA
- Apache Netbeans
- Eclipse
- Video tutoriál k používání Javy v IntelliJ IDEA.
- Video tutoriál 1 a 2 k používání Javy v Apache Netbeans.
- Java 21 Launch Event
- Ukázka z hodiny
Úkoly
- Pro vypracování všech úkolů použijte JShell. Na příště si nainstalujte IDE dle vlastní volby (ukázky na seminářích budou v IntellijIDEA).
- Mohou se hodit funkce z knihovny Math (vizte dokumentaci).
Napište funkci
primes
beroucí jeden argument typuint
, 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.Příklad:
primes(10);
vypíše:"2, 3, 5, 7, "
(bez uvozovek).Napište funkci
multiply
beroucí dva argumenty typuint
vracející jejich součin, ale používající z aritmetických operací pouze sčítání a odčítání.Příklad:
multiply(5,6);
vrátí30
.Napište funkci
printSquare
beroucí jeden argument typuint
, která na obrazovku vytiskne čtverec zadané velikost.Příklad:
printSquare(2)
vytiskne --
| |
| |
--
Tedy obecně čtverec z mezer velikosti n × n ohraničený znakem - shora a zespoda a znakem | zprava a zleva. Pro neplatná zadání funkce neudělá nic.Napište funkci
numberToString
vracející pro zadané číslo v rozsahu 1 až 10 jemu odpovídající anglické slovo a pro čísla mimo zadaný rozsah vrátí slovo “unknown”.Příklad:
numberToString(3)
vrátí řetězec"three"
.Výsledné kódy z JShellu exportujte do textového souboru a ten odevzdejte emailem s předmětem jj1-01 na tomas.urbanec@upol.cz do 26.9.2023, 14:59 CEST.
Nepovinné úkoly (usnadní vám práci v dalších seminářích)):
- Projděte si novinky v jednotlivých verzích Javy od 9. Získate tím hrubý přehled o vývoji Javy v posledních letech.
- Seznamte se s vybraným IDE.