Annak ellenőrzése, hogy létezik-e osztály Java-ban

1. Áttekintés

Egy osztály létezésének ellenőrzése hasznos lehet annak meghatározásakor, hogy egy interfész melyik implementációját használja. Ezt a technikát általában a régebbi JDBC telepítések során használják.

Ebben az oktatóanyagban feltárjuk a használat árnyalatait Class.forName () osztály létezésének ellenőrzésére a Java osztályúton.

2. Használata Class.forName ()

Az osztály létezését konkrétan a Java Reflection segítségével ellenőrizhetjük Class.forName (). A dokumentáció azt mutatja, hogy a ClassNotFoundException dobni fog, ha az osztály nem található.

2.1. Mikor várható ClassNotFoundException

Először írjunk egy tesztet, amely minden bizonnyal a-t dobja ClassNotFoundException hogy tudjuk, hogy pozitív tesztjeink biztonságosak:

@Test (várható = ClassNotFoundException.class) public void givenNonExistingClass_whenUsingForName_thenClassNotFound () dobja a ClassNotFoundException {Class.forName ("class.that.does.not.exist"); }

Tehát bebizonyítottuk, hogy egy nem létező osztály a-t dobja ClassNotFoundException. Írjunk egy tesztet egy olyan osztály számára, amely valóban létezik:

@Test public void givenExistingClass_whenUsingForName_thenNoException () dobja a ClassNotFoundException {Class.forName ("java.lang.String"); }

Ezek a tesztek ezt bizonyítják futás Class.forName () és nem fogja el a ClassNotFoundException egyenértékű az osztályúton létező meghatározott osztállyal. Ez azonban nem egészen tökéletes megoldás a mellékhatások miatt.

2.2. Mellékhatás: Osztály inicializálása

Alapvető hangsúlyozni, hogy osztályos rakodó megadása nélkül, Class.forName () futtatnia kell a statikus inicializálót a kért osztályon. Ez váratlan viselkedéshez vezethet.

Ennek a viselkedésnek a példájaként hozzunk létre egy osztályt, amely a-t dobja RuntimeException amikor a statikus inicializáló blokk végrehajtásra kerül, hogy azonnal tudhassuk, amikor végrehajtják:

public static class InitializingClass {static {if (true) {// engedélyezheti a kivétel dobását egy statikus inicializáló blokkba dobja az új RuntimeException (); }}}

Láthatjuk a forName () dokumentáció, amelyet dob ExceptionInInitializerError ha az ezzel a módszerrel kiváltott inicializálás sikertelen.

Írjunk egy tesztet, amelyre várható lesz ExceptionInInitializerError amikor megpróbálja megtalálni a mi Class inicializálása osztályrakodó megadása nélkül:

@Test (várható = ExceptionInInitializerError.class) public void givenInitializingClass_whenUsingForName_thenInitializationError () dobja a ClassNotFoundException {Class.forName ("elérési utat.InitializingClass"); }

Mivel egy osztály statikus inicializáló blokkjának végrehajtása láthatatlan mellékhatás, most láthatjuk, hogyan okozhat teljesítményproblémákat vagy akár hibákat. Nézzük meg, hogyan lehet kihagyni az osztály inicializálását.

3. Mesélés Class.forName () az inicializálás kihagyásához

Szerencsénkre van egy túlterhelt módszer forName (), amely elfogadja az osztály betöltőjét, és hogy végre kell-e hajtani az osztály inicializálását.

A dokumentáció szerint a következő hívások egyenértékűek:

Class.forName ("Foo") Class.forName ("Foo", igaz, this.getClass (). GetClassLoader ())

Megváltoztatásával igaz nak nek hamis, most írhatunk egy tesztet, amely ellenőrzi a Class inicializálásaanélkül, hogy elindítaná a statikus inicializálási blokkját:

@Test public void givenInitializingClass_whenUsingForNameWithoutInitialization_thenNoException () dobja a ClassNotFoundException {Class.forName ("path.to.InitializingClass", false, getClass (). GetClassLoader ()); }

4. Java 9 modulok

Java 9+ projekteknél van egy harmadik túlterhelés Class.forName (), amely elfogadja a Modul és a Húr osztály név. Ez a túlterhelés alapértelmezés szerint nem futtatja az osztályindítót. Emellett nevezetesen visszatér nulla amikor a kért osztály nem létezik, ahelyett, hogy dobna egy ClassNotFoundException.

5. Következtetés

Ebben a rövid bemutatóban az osztály inicializálásának mellékhatásait tártuk fel a használat során Class.forName () és rájöttek, hogy használhatja a forName () túlterhelések, hogy ez ne fordulhasson elő.

A forráskód és az oktatóanyag összes példája megtalálható a GitHubon.