2009-11-22

SCJP-6 02. Failų su klasėmis vardai ir metodas main()

Keletas mano pastebėjimų apie failų vardus bei metodą main().

Kiekvienas išeities failas (source-file) su plėtiniu .java gali turėti savyje daug deklaruotų klasių. Tačiau -- ne daugiau kaip vieną public klasę. Jos gali ir nebūti (!), bet jei public klasė apibrėžta, tuomet jos vardas turi sutapti su failo vardu (be plėtinio), kuriam klasė deklaruota. T.y. jei turime public klasę "Gyvis", ir tris kitas, package matomumo klases (pvz. "Briedis", "Begemotas" ir "Vandenynas"), tai visas šis ketvertas privalo būti patalpintas "Gyvis.java" faile. Jei public klasės nėra -- failo pavadinimas griežtų taisyklių neturi. Nepaisant to, abiem atvejais sukompiliavę išeities kodą gausime keturis atskirus .class failus (Gyvis.class, Briedis.class, Begemotas.class ir Vandenynas.class):

// Failo vardas privalo būti Gyvis.java
//Ne daugiau viena klasė gali būti deklaruota public
public abstract class Gyvis {}
class Briedis extends Gyvis {}
class Begemotas extends Gyvis{}
class Vandenynas {}
bei
// Failo vardas gali būti SCJP_1.java
abstract class Gyvis {}
class Briedis extends Gyvis {}
class Begemotas extends Gyvis{}
class Vandenynas {}

Metodas main(). Norint, kad JVM rastų šį metodą ir pradėtų programos vykdymą, jis privalo būti viešas (public), statinis (static) ir kaip parametrą naudoti eilučių masyvą (String [] args) arba, nuo Java 5, leisti perduoti nefiksuoto ilgio argumentų sąrašą (String... args).
Niuansai, kuriuos verta pastebėti:
  • nors ir statinis (t.y. "nepperrašomas" -- not overrideable) metodas gali būti apibrėžtas kaip "final". Prasmė? Neleisti paveldinčiai klasei apibrėžti  metodo tokiu pačiu vardu, ir tokiu būdu "paslėpti" esančiojo aukštesnėje klasėje (prisimenam, kad kalba eina apie statinius metodus, ne paprastus, instance metodus, todėl perrašymas -- override -- neegzistuoja). Šiuo klausimu diskusija buvo pradėjusi megztis JavaRanch forume.
  •  klasei nebūtina pačiai turėti statinį main() metodą. Užtenka, kad jis bus realizuotas kuriame nors iš "protėvių".
Apibendrinant:
// Failas KeliosKlases.java
class GrandParent {
  final public static void main(String ... args) {
    System.out.println(">>> Tai yra GrandParent klasės main(...) metodas");
  }
  class Parent extends GrandParent {}
  class MyClass extends Parent {}
}
Kompiliuojam ir vykdom MyClass:
javac
KeliosKlases.java

java MyClass
...
> Tai yra GrandParent klasės main(...) metodas

Komentarų nėra: