Python versus Java
- Hello World
- Kompilering og å kjøre programmet fra terminalen
- Variabler og statiske typer
- Noen enkle typer
- Typekonvertering
- Operasjoner
- Lister
- Betingelser
- Løkker
- Oppslagsverk
- Mengder
- Metoder og funksjoner
Hello World
For å i det hele tatt ha et fungerende program i Java, trengs det en del mer kode enn i Python. Hvor Python enkelt nok begynner å lese kommandoer fra toppen av filen, trenger Java at koden som skal kjøres er definert i en klasse; og at denne klassen har en metode med den magiske signaturen public static void main(String[])
. Det er denne metoden som blir kalt når programmet starter.
|
|
I eksemplene som sammenligner Python og Java videre på denne siden vil vi av plasshensyn ikke alltid inkludere hele dette oppsettet, men det må likevel alltid være med for at koden skal kjøre; og det vil være tilstede dersom du klikker på «se steg» -knappen.
I løpet av dette kurset skal du lære om betydningen av alle de magiske ordene og tegnene vi kan se i Java-programmet over. Noe dukker opp på dag én, andre ting overser vi relativt lenge og kommer tilbake til senere i kurset.
Kompilering og å kjøre programmet fra terminalen
Å kjøre Hello World -programmet vi skrev over fra terminalen gjøres med én kommando i Python, mens Java krever to: først skal kildekoden kompileres med javac
-programmet, deretter kan programmet kjøres med «java runtime environment» (java
-programmet).
|
|
Når javac
-programmet kjøres, vil det bli opprettet nye filer med filendelse .class
. I eksempelet over vil det opprettes en fil HelloWorld.class
. Denne filen inneholder kode i et programmeringsspråk som kalles «java bytecode». Denne kompilerte koden er en slags mellomting mellom menneskeleselig kode og maskinleselig kode. Dersom du av en eller annen grunn åpner den i en tekst-editor vil du se en blanding av forståelige og uforståelige symboler.
Dersom man kjører et Java-program ved å trykke på «kjør» -knappen i en kodeeditor som Visual Studio Code eller Intellij, vil begge stegene bli gjort automatisk. Forskjellen vi merker som utviklere er at selve kompileringsprosessen (javac
-steget) kan krasje – og dermed vil ikke Java -programmet engang begynne å kjøre. I Python ville programmet kanskje ikke krasjet før kjøringen faktisk kom til linjen hvor noe var feil.
Fordelen med å kompilere koden før den kjøres er først og fremst effektivitet. Under kompileringsprosessen kan kompilatoren identifisere deler av koden som kan skrives på en mer effektiv måte, og dessuten er det raskere å oversette bytecode til maskinkode enn det er å oversette menneskelig-leselig kode direkte. I følge denne testen er ren Java ca 30 ganger raskere enn ren Python (men nøyaktig hvor stor forskjellen er vil variere mye avhengig av hvilken oppgave som skal utføres, og også av hvilken fortolker/kjøretidsmiljø man benytter seg av).
Variabler og statiske typer
Til forskjell fra Python, har variabler en type i Java. Vi sier at Java er et statisk typet språk (i motsetning til Python som er et dynamisk typet språk).
|
|
Første gang en variabel benyttes, må man oppgi typen. Typen kan ikke endres, og skal heller ikke oppgis ved senere bruk.
Noen enkle typer
De vanligste typene er omtrent de samme i Python som i Java:
|
|
De oppfører seg nesten likt også. Det er imidlertid noen subtile forskjeller i int
-typen: mens en int i Python kan ha ubegrenset stor verdi, kan en int i Java kun eksistere i intervallet [-2147483648, 2147483647]. For å få samme type int som Python, kan man med Java bruke BigInteger i stedet; men det gjør vi av effektivitetshensyn kun når det faktisk er nødvendig (altså nesten aldri).
Typekonvertering
Typekonvertering mellom de primitive typene, som for eksempel int
, double
og boolean
, kan gjøres ved såkalt casting. Dette gjøres ved å sette den nye typen i parenteser foran verdien som skal konverteres:
|
|
Konverteringen til og fra strenger er litt annerledes, og krever at vi bruker funksjoner laget spesielt for formålet:
|
|
Operasjoner
Presedensreglene for operatorer er omtrent de samme i Python og Java. Se offisiell presdenstabell.
Operatorsymboler er også stort sett de samme i Python og Java, men med unntak for noen logiske operatorer:
|
|
Divisjon
Divisjon-operatøren /
oppfører seg litt annerledes enn i Python. I Java utfører denne operatøren heltallsdivison når den brukes med int
-verdier, mens den i Python alltid utfører flyttallsdivisjon. Operatøren //
finnes ikke i Java (dette brukes i stedet for å angi kommentarer i kildekoden).
|
|
I Java er det mulig å bruke ++
og --
som operatører på variabler av typen int
. Dette gjør at variabelen øker eller minker med 1. Dersom ++
eller --
skrives før variabelen, endres verdien i variabelen før resten av linjen utføres, mens dersom de skrives etter variabelen, endres verdien etter at resten av linjen er utført.
Det er også mulig å bruke +=
og -=
, som gjør at variabelen øker eller minker med et gitt tall slik som i Python.
|
|
Lister
Lister er en av de mest brukte datatypene i Python, og det samme gjelder i Java. I Java finnes det sågar flere ulike liste-varianter; den som ligner mest på en liste slik vi kjenner det fra Python er ArrayList. Men det er likevel noen forskjeller:
- alle elementene i en liste må ha samme type, og
- vi må importere ArrayList øverst i filen med linjen
import java.util.ArrayList;
(klikk «se steg» under for å se eksempel), og - hvis vi skal initialisere en liste med gitte elementer, må vi bruke
Arrays.asList
som vist i eksempelet under. Da må vi i så fall også importerejava.util.Arrays
øverst i filen.
|
|
I Java er det også noe som kalles array, som er en liste man ikke kan endre størrelse på. Selv om syntaksen for array’er minner veldig om Python sin syntaks for lister og på mange måter er penere og lettere, anbefaler vi likevel å bruke ArrayList. Grunnen er først og fremst fordi array’er i Java virker dårlig sammen med generiske typer, som vi kommer til senere; når det i tillegg ikke er mulig å endre størrelsen på arrays, blir derfor ArrayList konseptuelt sett nærmere det vi kjenner som en liste i Python. ArrayList er også anbefalt i praksis.
Vi kommer likevel borti array’er i Java, fordi dette ofte er den type liste som benyttes som parametertype eller returtype for metoder i Java sitt standardbibliotek. Du kan lese mer i kursnotater om array og lister.
Betingelser
Betingelser fungerer omtrent på samme måte i Python og Java. Merk at betingelsene alltid må være inni paranteser i Java, mens de ikke trenger det i Python.
|
|
Løkker
While-løkker
fungerer likt i Python og Java.
|
|
For-each-løkker
Java har to forskjellige typer for-løkker. For-løkker over en samling med elementer, for eksempel over elementene i liste, skrives omtrent på samme måte som i Python. Dette kalles en for-each-løkke i Java.
|
|
Standard for-løkker
Java har også det vi kaller en «standard» for-løkke. Det nærmeste motstykket til denne løkken i Python er en for-løkke over et range-objekt.
|
|
Standard for-løkke er vanlig for å iterere over indekser i en liste, eller for å iterere et gitt antall ganger, og spiller ofte samme rolle som en for-løkke over et range-objekt gjør i Python – selv om den egentlig er langt mer fleksibel.
Den standard for-løkken har tre setninger skilt med ;
samlet på én linje. I eksempelet over:
int i = 10
er initialiseringssetningen. Denne setningen kjøres bare én gang, før løkken starter.i < 100
er betingelsen. Så lenge betingelsen er sann, gjøres nye iterasjoner av løkken.i += 5
er oppdateringssetningen. Denne setningen kjøres etter hver iterasjon av løkken.
En standard for-løkke er like fleksibel som en while-løkke. Faktisk er en for-løkke med en tom initialiseringssetning og en tom oppdateringssetning nøyaktig det samme som en while-løkke.
|
|
Vi kan også utnytte alle setningsdelene i for-løkken til å skrive samme kode litt mer kompakt. Legg merke til vi bruker count
i initialiseringssetningen og betingelsen, men endrer num
i oppdateringssetning. Dette er litt utradisjonelt, men fullt mulig med standard for-løkker.
// Bruker count = 0 som initialsieringssetning, og num++ som oppdateringssetning
int num = 1;
for (int count = 0; count < 9; num++) {
if (num % 7 == 0) {
count++;
}
}
System.out.println(num - 1);
Evig løkke, break og continue
Break og continue virker på samme måte som i Python. For å lage en evig løkke, bruker vi en standard for-løkke med tom betingelse (eventuelt er det også fullt mulig å bruke en while(true) -løkke)
|
|
Oppslagsverk
Oppslagsverk kalles for map i Java og tilsvarer omtrent et dictionary i Python. Java har flere ulike typer oppslagsverk, men HashMap er det som ligner mest på Python sitt dict
. De mest fremtredene forskjellene er at
- Java sitt
HashMap
krever at vi bruker samme type for alle nøklene i oppslagsverket, og også samme type for alle verdiene, og - vi må importere
HashMap
-klassen frajava.util
-pakken for å kunne bruke den (dette vises i eksempelet kun dersom du klikker «se steg»).
|
|
Mengder
Java har flere ulike typer mengder, men HashSet er det som ligner mest på Python sitt set
. De mest fremtredene forskjellene er at
- Java sitt
HashSet
krever at vi bruker samme type for alle verdiene, og - vi må importere
HashSet
-klassen frajava.util
-pakken for å kunne bruke den (dette vises i eksempelet kun dersom du klikker «se steg»).
|
|
Metoder og funksjoner
I Java kaller man vanligvis funksjoner for metoder.
Forskjellen mellom begrepene metode og funksjon kommer litt an på øyet som ser:
- En programmerer vil gjerne si at en metode er en funksjon som virker på et objekt. I dette perspektivet er metoder en undergruppe av funksjoner.
- En matematiker vil si at begrepet funksjon innebærer at det ikke finnes sideeffekter, bare returverdi; og at en funksjon alltid vil gi samme returverdi såfremt argumentene er de samme. I en kontekst hvor alle navngitte prosedyrer med input og potensielt en returverdi kalles for metoder (slik som i Java) kan dette perspektivet la oss tenke på funksjoner som en undergruppe av metoder.
Fordi alle funksjoner i Java teknisk sett er knyttet til et objekt gir ikke den første distinksjonen oss noen særlig merverdi, og begrepene funksjon og metode blir i praksis synonymer. Det kan derfor gi mening å forholde seg til matematikernes perspektiv – men vær i så fall bevisst på at dette er et perspektiv som ikke er spesielt vanlig i programmeringssammenheng.
Man definerer en metode ved å angi
- om metoden skal være
public
,private
,protected
eller ingen av delene,- (dette bestemmer hvilke andre steder i kildekoden man får lov til å kalle på metoden. Vi kommer tilbake til dette når vi diskuterer innkapsling senere i kurset. Foreløpig ignorerer vi det bortsett fra i
main
-metoden, som må værepublic
)
- (dette bestemmer hvilke andre steder i kildekoden man får lov til å kalle på metoden. Vi kommer tilbake til dette når vi diskuterer innkapsling senere i kurset. Foreløpig ignorerer vi det bortsett fra i
- om metoden skal være
static
eller ikke,- (at en metode er static betyr at den er knyttet til selve klassen den er definert i, men ikke til instansene av klassen. Om du leser dette i uke 1 av kurset og forrige setning ikke gav noen som helst mening, fortvil ikke; vi kommer tilbake til dette når vi lærer om klasser og objekter.)
- metodens returtype (eller
void
hvis metoden ikke har returverdi), - navnet på metoden,
- en liste med 0 eller flere parametre omsluttet av parenteser, og
- kroppen til metoden omsluttet av krøllparenteser.
|
|