Jak uzyskać wszystkie zajęcia w pakiecie?Introspekcja pakietu Java
Odpowiedz
Nie możesz. Zajęcia mogą odbywać się za pośrednictwem wielu różnych programów ładujących klasy, w tym zdalnych.
Nie ma globalnego sposobu, aby to zrobić. Biorąc to pod uwagę, jeśli wiesz, skąd pochodzą twoje klasy, możesz przejść do katalogu pliku jar lub systemu plików.
Jest to fragment z here że robi dokładnie to, co chcesz, zakładając klas można znaleźć lokalnie:
private static Class[] getClasses(String packageName)
throws ClassNotFoundException, IOException {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
assert classLoader != null;
String path = packageName.replace('.', '/');
Enumeration<URL> resources = classLoader.getResources(path);
List<File> dirs = new ArrayList<File>();
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
dirs.add(new File(resource.getFile()));
}
ArrayList<Class> classes = new ArrayList<Class>();
for (File directory : dirs) {
classes.addAll(findClasses(directory, packageName));
}
return classes.toArray(new Class[classes.size()]);
}
private static List<Class> findClasses(File directory, String packageName) throws ClassNotFoundException {
List<Class> classes = new ArrayList<Class>();
if (!directory.exists()) {
return classes;
}
File[] files = directory.listFiles();
for (File file : files) {
if (file.isDirectory()) {
assert !file.getName().contains(".");
classes.addAll(findClasses(file, packageName + "." + file.getName()));
} else if (file.getName().endsWith(".class")) {
classes.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6)));
}
}
return classes;
}
Czy to działa z klasami słoików? –
O ile mogę powiedzieć, to się nie powiedzie, jeśli masz słoik (-1), ale jest przyzwoitym rutyną szukania plików .class dla odkrycia (+1), więc możesz się zepsuć :) –
Powyższy kod nie tylko zakłada, że klasy z danego pakietu są lokalne, ale także, że wszystkie zostały załadowane przez ten sam program ładujący klasy I nie zostały spakowane. – ChssPly76
Java nie mają odkrycia.
Większość produktów, które mają możliwość dodawania (odkrywania) nowych klas, może mieć plik tekstowy opisujący "Rozszerzenia programów" lub określony katalog, w którym można umieścić klasy lub słoiki z wykorzystaniem sztuczki, takiej jak opisany @JG. (To właśnie robi eclipse i jest zalecane dla każdego rozwiązania, w którym użytkownik może ręcznie dodać nowy moduł).
Nie zapomnij o API SPI dla wtyczek. Zapewniają one rozsądnie eleganckie rozwiązanie dla frameworków wtyczek. – jsight
Oto dokładniejszy sposób rozwiązania tego problemu dla słoików, w oparciu o pomysł opublikowany przez JG.
/**
* Scans all classloaders for the current thread for loaded jars, and then scans
* each jar for the package name in question, listing all classes directly under
* the package name in question. Assumes directory structure in jar file and class
* package naming follow java conventions (i.e. com.example.test.MyTest would be in
* /com/example/test/MyTest.class)
*/
public Collection<Class> getClassesForPackage(String packageName) throws Exception {
String packagePath = packageName.replace(".", "/");
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Set<URL> jarUrls = new HashSet<URL>();
while (classLoader != null) {
if (classLoader instanceof URLClassLoader)
for (URL url : ((URLClassLoader) classLoader).getURLs())
if (url.getFile().endsWith(".jar") // may want better way to detect jar files
jarUrls.add(url);
classLoader = classLoader.getParent();
}
Set<Class> classes = new HashSet<Class>();
for (URL url : jarUrls) {
JarInputStream stream = new JarInputStream(url.openStream()); // may want better way to open url connections
JarEntry entry = stream.getNextJarEntry();
while (entry != null) {
String name = entry.getName();
int i = name.lastIndexOf("/");
if (i > 0 && name.endsWith(".class") && name.substring(0, i).equals(packagePath))
classes.add(Class.forName(name.substring(0, name.length() - 6).replace("/", ".")));
entry = stream.getNextJarEntry();
}
stream.close();
}
return classes;
}
-1 brak dokumentacji, a nawet wskazówki na temat tego, co robi, +2, ponieważ wygląda na to, że skanuje ścieżkę klas i zawiera słoiki! więc zarabiasz +1 :) –
(Cóż, nie było podpowiedzi, co robi .. Biorę to z powrotem). –
Dodano nagłówek javadoc dla lepszego wyjaśnienia. :) – toluju
Również zauważ [ten wpis] (http://stackoverflow.com/q/520328/1005481). –