Muutujad
Sissejuhatus
Muutuja on nimega varustatud koht arvuti mälus, kuhu programm saab oma käitamisaja jooksul andmeid salvestada. Javas kasutatakse muutujaid väärtuste hoidmiseks, lugemiseks ja muutmiseks programmi töö käigus.
Java on tüübikindel programmeerimiskeel, mis tähendab, et iga muutuja tüüp peab olema määratud ning sellest tuleb kogu aeg kinni pidada.
Igal muutujal peab olema nimi, tüüp ja väärtus.
Deklaratsioon ja initsialiseerimine
Muutuja kasutamiseks Javas tuleb see esmalt deklareerida ning enne kasutamist ka initsialiseerida:
- Deklaratsioon määrab muutuja tüübi ja nime
- Initsialiseerimine määrab muutujale algväärtuse
Kõige levinum viis muutuja loomiseks on muutuja ühel real deklareerimine ja initsialiseerimine.
Javas käib muutujate loomine järgneva mustri järgi: TYPE VARIABLE_NAME = VALUE;
Näiteks:
int x = 1;
String name = "Ago";
Ehk esimese rea puhul on muutuja tüübiks int ehk täisarv, nimeks x ning väärtuseks 1.
Teise rea puhul on muutuja tüübiks String ehk sõne, nimeks name ning väärtuseks Ago.
Samuti on võimalik muutujat deklareerida ka ilma sellele väärtust andmata. Sellisel juhul kehtivad kindlad reeglid.
Lokaalsed muutujad
Lokaalsed muutujad ehk meetodisisesed muutujad ei saa vaikimisi väärtust.
Näiteks:
int x;
System.out.println(x); // Error
Kui proovida kasutada initsialiseerimata muutujat, tekib kompileerimisviga:
java: variable x might not have been initialized
Isendi- ja staatilised muutujad
Klassitasemel deklareeritud muutujad saavad endale vaikimisi väärtuse, isegi kui neid ei initsialiseerita käsitsi.
Näiteks:
public class Main {
int x; // default value is 0
boolean b; // default value is false
String s; // default value is null
public static void main(String[] args) {
Main a = new Main();
System.out.println(a.x); // prints 0
System.out.println(a.b); // prints false
System.out.println(a.s); // prints null
}
}
Tüübikindlus
Kuna Java on staatiliselt tüübitud (ehk tüübikindel) keel, siis igale muutujale määratakse kompileerimise ajal tüüp ning antud muutujale saab omistada ainult sellele tüübile sobivaid väärtusi.
Mitteühilduvate tüüpide tõttu tekiks kompileerimisviga.
Näiteks:
int x = 1;
x = "Ago"; // Error
Antud näite põhjal tekiks järgmine kompileerimisviga:
java: incompatible types: java.lang.String cannot be converted to int
Tüübikindlus aitab vältida loogikavigu, parandada koodi loetavust ning tuvastada vigu enne programmi käivitamist.
Muutuja skoop
Samuti mängib Javas olulist rolli ka see, kus muutuja deklareeriti.
Muutuja skoop määrab, millises programmi osas on muutuja nähtav ja kasutatav.
Skoope saab jaotada kolmeks: lokaalne-, isendi- ja staatiline muutuja.
Lokaalne muutuja
Lokaalne muutuja kehtib ainult meetodis või koodiplokis, kus see deklareeritud on.
Näiteks:
if (true) {
int x = 5;
System.out.println(x); // 5
}
System.out.println(x); // Error
Viimase x väljakutse kohal programm ei oska muutujat tuvastada ning tekib järgnev kompileerimisviga:
java: cannot find symbol
symbol: variable x
location: class Main
Isendimuutuja
Isendimuutujad on deklareeritud klassitasemel ning on seotud konkreetse objekti isendiga.
Näiteks:
class Student {
String name; // instance variable
}
public class Main {
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
s1.name = "Ago";
s2.name = "Taavi";
System.out.println(s1.name); // Ago
System.out.println(s2.name); // Taavi
}
}
Antud näite puhul, igal Student-objektil on määratud unikaalne nimi ehk hoiab erinevaid väärtusi.
Ühes objektis tehtud muudatused ei mõjuta teisi objekte.
Staatiline muutuja
Staatiline muutuja kuulub klassile, mitte objektile.
Seda deklareeritakse koos static märksõnaga.
Näiteks:
class Student {
static int studentCount = 0; // static variable
Student() {
studentCount++;
}
}
public class Main {
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
System.out.println(Student.studentCount); // 2
}
}
Antud näite puhul luuakse muutuja studentCount ühe korra, kõik Student-tüüpi objektid kasutavad ja muudavad sama muutujat.
Muutujale pääsetakse ligi läbi klassi, mitte objekti.
Teisisõnu tekib globaalne muutuja, mis on jagatud kõikide seda tüüpi objektide vahel.
final-keyword ehk muutumatu muutuja
Kui on soov luua muutuja, mille väärtust peale initsialiseerimist muuta ei saa, siis on võimalik muutuja deklaratsioonile juurde lisada final-märksõna.
final tähistab, et antud muutuja väärtust ei saa peale initsialiseerimist muuta.
Näiteks:
final int x = 100;
x = 200; // Error
Uue väärtuse omistamisel tekiks järgnev kompileerimisviga:
java: cannot assign a value to final variable x
final-märksõna kasutatakse tavaliselt konstantide loomiseks koos static-märksõnaga.
Nimereeglid
Java puhul järgitakse järgnevaid reegleid muutujate nimetamisel:
- Nimi võib alata tähe, alakriipsu (
_) või dollarimärgiga ($), kuid viimast kaht pole soovitatud kasutada. - Nimi ei tohi alata numbriga ning ei tohiks olla mõni Java märksõna
Samuti tuleks järgida järgnevaid tavasid:
- Muutujate nimetamisel kasutatakse camel case stiili ehk nimi algab väikese tähega. Kui muutuja nimi koosneb mitmest sõnast siis need kirjutatakse kokku ning iga uus sõna algab suure tähega.
- Muutuja nimi võiks olla lühike kuid tähendusrikas. Antud muutuja põhimõte peaks nimetusest välja tulema.
- Ühetähelisi muutujaid võiks vältida, kui neid parasjagu ei kasutata tsüklites (ajutiste muutujate puhul on selline nimetus sobiv).
- Staatilised
finalmuutujad nimetatakse läbivalt suurte tähtedega ning iga sõna on alakriipsuga (_) eraldatud.
Näited:
// Correct examples - camelCase, meaningful names
int age;
double averageScore;
String studentName;
boolean isActive;
// Technically correct but should be avoided
int _count; // Commonly used for assigning class variables via arguments.
// We have `this` keyword for said use-case.
// this.count = count is better than _count = count
int $sum; // Reserved for compiler use.
// Bad naming examples
int a;
int x1;
double data;
String temp;
// static final constants
static final int MAX_SIZE = 100;
static final String DEFAULT_ROLE = "USER";
// These will throw an error
int 1number;
int class;
int public;
Ühetähelised muutujad on lubatud tsüklites, kuna need on ajutised:
for (int i = 0; i < 10; i++) {
// ...
}
var
Antud peatükis käime var märksõna lühidalt läbi, kuid selle kohta tuleb hiljem täpsem artikkel, kuna antud märksõnal on oma kindlad nüansid.
Alates Java versioon 10-st on võimalik kasutada ka var märksõna, mis võimaldab muutuja tüübi automaatset tuletamist kompilaatori poolt.
Näiteks:
var number = 10; // Type - int
var text = "Java"; // Type - String
var puhul on oluline teada, et ta ei ole omaette tüüp, ta on lihtsalt märksõna, mis annab kompilaatorile mõista et muutuja tüüp tuleb tuletada kompileerimise ajal algväärtuse põhjal.
Kompilaator määrab muutujale konkreetse ja muutumatu tüübi. Oluline on teada, et see ei muuda antud muutuja tüüpi dünaamiliseks ehk tüüp ei muutu programmi käivitamise ajal.
Muutuja käitub tavapäraselt edasi, näiteks:
var x = 5; // Type - int
x = 10; // OK
x = "test"; // Error
Seega var võimaldab koodi loetavamaks muuta, kuid ta ei muuda Javat dünaamiliselt tüübitud keeleks.
var-i täpsemad reeglid on välja toodud eraldi peatükis.