Klasse existiert prüfen

wersi77

Aktives Mitglied
Hallo zusammen,

ich würde gerne prüfen, ob eine Klasse innerhalb meines Programms existiert:

Java:
public class Test {
    public static void main(String[] args) throws InterruptedException {
        try {
            Class cls = Class.forName("HelloWorld");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

Aber es kann auch sein, dass eine Klasse in einem Package verlegt wurde, z.B. nach mypackage.HelloWorld
Ist es irgendwie möglich nur durch Angabe des Klassen-Namens nach der Verügbarkeit der Klasse zu prüfen?
Das folgende bringt mir also nichts:
Java:
Class cls = Class.forName("mypackage.HelloWorld");

Hat jemand einen Lösungsansatz hierfür?
Vielen Dank
 
Also erstmal: Eine Klasse ist nur eindeutig durch ihren kompletten vollqualifizierten Klassennamen (mit Package).
Wenn du aber weisst, dass es nur in _einem_ Package die Klasse HelloWorld gibt, dann kannst du auch "Classpath Scanning" verwenden.
Da gibt es Libraries für. Effektiv gucken die, welche Dateisystem-Verzeichnisse und/oder JAR Dateien in dem java.class.path stehen, öffnet die im Dateisystem bzw. mit einem Zip Input Stream und scanned die durch.
Es gibt nativ in Java aber _keine_ Möglichkeit, einfach zu sagen "Gib mir alle Klassen, deren Namen auf *HelloWorld enden." (nochmal: der JVM-interne Name einer Klasse ist immer der vollqualifizierte Name, also mit Package).
 
Um noch etwas auszuholen was das ClassPath-Scanning angeht. Die Idee hinter dem Java System ist grundsaetzlich das nur Klassen geladen werden, welche auch gebraucht werden. Im ClassPath kann alles drinnen sein, von einem Verzeichnis mit .class Dateien, zu einem JAR, zu irgendeinem obskuren System welches Klassen on-the-fly generiert. Deswegen gibt es von der JRE aus keine unmittelbare Moeglichkeit sich *alle* Klassen zu holen, da dies eine komplett undefinierte Menge ist vom System aus. Kann ja sein dass du einen Klassenpfad hast welcher als letzte Instanz einen ClassLoader hat welcher Klassen dynamisch erzeugt (aus welchem Grund auch immer). Ein weiteres Beispiel waere wenn Klassen ueber das Netzwerk gestreamed werden, da will man dann auch nicht unbedingt alle holen.

Ebenfalls zu beachten hierbei waere dann Speicherverbrauch. Klassen welche einmal geladen wurden gehen nicht mehr so einfach weg. Also ein scannen wuerde alle Klassen laden, und inwiefern diese dann wieder von der Garbage Collection freigegeben werden ist dann fragwuerdig (ich glaube sogar der ClassLoader der Klasse muss weg sein).
 
Also ein scannen wuerde alle Klassen laden
Das ist so nicht ganz korrekt. Das Scannen lädt keine Klassen (z.B. per Reflection), sondern schaut sich in Verzeichnissen und JAR-Dateien des Classpaths nur an, welche Dateien dort vorhanden sind (und parsed den Bytecode eventuell einfach, z.B. per ASM, um auch zu überprüfen, dass es sich dabei um eine Klasse (und kein Interface oder Enum handelt - je nachdem, ob man das will). Zumindest funktionieren so alle Classpath-Scanner, die ich kenne, z.B. auch der in Spring. Kein Classpath Scanner _lädt_ die Klassen tatsächlich in der JVM über einen ClassLoader.
Effektiv muss man eigentlich nur gucken, ob die Datei auf ".class" endet und evtl noch, ob das byte im class file, welches angibt, welchen Typ die Klasse/Interface/Enum hat, einen bestimmten Wert hat.
 
Das ist so nicht ganz korrekt. Das Scannen lädt keine Klassen (z.B. per Reflection), sondern schaut sich in Verzeichnissen und JAR-Dateien des Classpaths nur an, welche Dateien dort vorhanden sind (und parsed den Bytecode eventuell einfach, z.B. per ASM, um auch zu überprüfen, dass es sich dabei um eine Klasse (und kein Interface oder Enum handelt - je nachdem, ob man das will). Zumindest funktionieren so alle Classpath-Scanner, die ich kenne, z.B. auch der in Spring. Kein Classpath Scanner _lädt_ die Klassen tatsächlich in der JVM über einen ClassLoader.
Effektiv muss man eigentlich nur gucken, ob die Datei auf ".class" endet und evtl noch, ob das byte im class file, welches angibt, welchen Typ die Klasse/Interface/Enum hat, einen bestimmten Wert hat.

Ja, das stimmt.
 

Zurück
Oben