Liigu peamise sisu juurde

Import-laused

Sissejuhatus

Eelmises peatükis tutvusime pakkidega ja Java nimeruumiga. Igal klassil on täispikk nimi, mis sisaldab endas ka paki nime, näiteks java.util.ArrayList või university.students.Student. Nende nimede kirjutamine pikal kujul muudaks koodi raskemini loetavamaks:

java.util.ArrayList<String> names = new java.util.ArrayList<>();
java.util.HashMap<String, Integer> scores = new java.util.HashMap<>();

Selle lahendamiseks on Javas olemas import-laused. Import-lause võimaldab kasutada klassi lühinime selle täieliku nime asemel. See võimaldab programmeerijal kirjutada java.util.ArrayList asemel lihtsalt ArrayList läbinisti üle terve faili.

Import-lause

Import-lauseid deklareeritakse Java faili ülemises pooles, pärast paki deklaratsiooni ja enne klassi deklaratsiooni. Näiteks:

package university.courses;

import java.util.ArrayList;
import java.util.HashMap;

public class Course {
private ArrayList<String> studentNames = new ArrayList<>();
private HashMap<String, Integer> grades = new HashMap<>();
}

Samuti on võimalik importida ka enda poolt loodud klasse:

package university.courses;

import university.students.Student;
import university.administration.AdminOffice;

public class Course {
private Student instructor;

public void registerStudent(Student student) {
// ...
}
}

Tuletame meelde, et klasse, mis asuvad samas pakis ei pea eraldi importima, need on üksteisele automaatselt nähtavad.

Wildcard imports

Klasside ükshaaval importimise asemel on võimalik ka kõiki klasse korraga importida. Selleks on olemas wildcard import ehk kui paki lõppu lisatakse .*:

import java.util.*;    // imports ArrayList, HashMap, List, Map, and everything else in java.util

See importib kõik klassid, mis on ainult seal pakis. Alampakkides olevaid klasse ei importita, näiteks import java.util.* ei importi java.util.concurrent.locks.Lock klassi nimeruumi.

Kuigi wildcard-id võivad tunduda mugavad, siis praktikas välditakse nende kasutust. Wildcard import teeb koodi umbmääraseks:

  • Ei ole kohe näha, milliseid klasse tegelikult kasutatakse
  • Võib suurtes failides tekitada nimede konflikte
  • IDE-d haldavad neid küll hästi, kuid lugemisel on konkreetsed import-laused selgemad

Kompileerimise seisukohalt ei ole * aeglasem ega erinev — tegemist on puhtalt loetavuse küsimusega.

Staatilised impordid

Samuti on võimalik import-lauseid kombineerida static märksõnaga. See võimaldab teisest klassist pärit staatilist meetodit või välja kasutada ilma selle ette klassi nime kirjutamata. Näiteks:

import static java.lang.Math.PI;
import static java.lang.Math.sqrt;

public class Circle {
private double radius;

public Circle(double radius) {
this.radius = radius;
}

public double area() {
return PI * radius * radius; // instead of Math.PI
}

public double hypotenuse(double a, double b) {
return sqrt(a * a + b * b); // instead of Math.sqrt()
}
}

Staatilised importid on kasulikud, kui mõni meetod või konstant on tihedalt koodis kasutuses ning klassi nimi ei lisa koodile mingit selgust. Samas võiks neid kasutada mõistlikuse piires, kuna on olukordi, kus klassi nime eemaldamine teeb koodi raskemini loetavamaks.

Kõiki klasse ei pea importima

Javas on kahte tüüpi klasse, mida ei pea eraldi nimeruumi sisse importima. Nendeks on:

  • Klassid, mis kuuluvad java.lang pakki - String, System, Math jne. Need kõik on igas Java failis automaatselt saadaval.
  • Klassid mis asuvad samas pakis
// These work without any import
String name = "Alice";
System.out.println(name.length());
int max = Math.max(10, 20);

Module imports

Alates Java 25-st on võimalik ka importida mooduleid (JEP 511). Selle asemel et importida üksikuid klasse või tervet pakki, võimaldab moodulite importimine nimeruumi sisse tuua kõik avalikud klassid, mida antud moodul endas omab. Kõik läbi ühe import-lause:

import module java.base;

Antud näite puhul on kõik klassid java.base moodulist nimeruumi sisse toodud (nt: ArrayList, HashMap jne), ilma et neid peaks eraldi deklareerima. Võrdluseks:

import java.util.ArrayList;          // single-type import  — one class
import java.util.*; // wildcard import — one package
import module java.base; // module import — one entire module (many packages)

Nimeruumi konfliktid

Mooduli importimine toob endaga kaasa ka samad ohud, mida toovad wildcard importid, kuid suuremal mastaabil. Näiteks kui kahel moodulil on samanimeline klass:

import module java.base;   // exports java.util.Date
import module java.sql; // also exports java.sql.Date

Date d = new Date(); // compile error — Date is ambiguous

Antud juhul kompilaator ei oska otsustada, millist Date klassi mõeldakse. Seda konflikti saab lahendada tavalise import-lausega, kus täpsustatakse ära, millist klassi täpselt kasutada:

import module java.base;
import module java.sql;

import java.util.Date; // now Date unambiguously refers to java.util.Date
info

Selle peatüki kirjutamise hetkel (veebruar 2026) on moodulite importimine Java 25-s äsja tutvustatud. Pole veel selge, kui laialdast kasutust see Java ökosüsteemis leiab ning millised parimad tavad sellest välja kujunevad. Seetõttu tuleks seda funktsionaalsust päris projektides kasutada ettevaatlikult, kuni tekivad täpsemad kogukonna soovitused.