[英]Dynamic Class Loading in Java (Enumeration)
我有一個問題,我希望使用反射在運行時生成一組類中的一個的實例。 但是,我遇到了麻煩。 我想讓所有涉及的類都注冊自己,這樣就可以從GUI中選擇合適的類。 我可以在每個文件中使用靜態代碼塊來提供整潔的OO解決方案。 但是,java類加載器在需要時專門加載類,因此如果尚未使用所需的類,則不會注冊它。
如果沒有直接提供靜態名稱列表,或者運行底層的類/ java文件(無論如何打包到jar中都會破壞),有沒有辦法強制加載某些包的類?
基本上,我希望能夠從指定的超類添加新類,而無需更改/添加任何其他代碼。
澄清一下,你的問題不是關於“Java中的動態類加載”,而是關於動態類枚舉 - 你知道如何加載類,你只是不知道你想要什么類。
谷歌快速推出了這個頁面: http : //forums.sun.com/thread.jspa?threadID = 341935&start = 0&tstart = 0
從該頁面開始,這里有一些應該有效的示例代碼:
public static Class[] getClasses(String pckgname)
throws ClassNotFoundException {
ArrayList<Class> classes = new ArrayList<Class>();
// Get a File object for the package
File directory = null;
try {
ClassLoader cld = Thread.currentThread().getContextClassLoader();
if (cld == null) {
throw new ClassNotFoundException("Can't get class loader.");
}
String path = '/' + pckgname.replace('.', '/');
URL resource = cld.getResource(path);
if (resource == null) {
throw new ClassNotFoundException("No resource for " + path);
}
directory = new File(resource.getFile());
} catch (NullPointerException x) {
throw new ClassNotFoundException(pckgname + " (" + directory
+ ") does not appear to be a valid package");
}
if (directory.exists()) {
// Get the list of the files contained in the package
String[] files = directory.list();
for (int i = 0; i < files.length; i++) {
// we are only interested in .class files
if (files[i].endsWith(".class")) {
// removes the .class extension
classes.add(Class.forName(pckgname + '.'
+ files[i].substring(0, files[i].length() - 6)));
}
}
} else {
throw new ClassNotFoundException(pckgname
+ " does not appear to be a valid package");
}
Class[] classesA = new Class[classes.size()];
classes.toArray(classesA);
return classesA;
}
Spring Framework基於注釋進行組件掃描。
例如,查看ClassPathScanningCandidateComponentProvider類。 您可以基於接口/基類執行相同的操作,它應該適用於所有LOCAL類。 對於java中的所有類,無法執行此操作。
Class.forName(“class name here”);
你將擁有一個帶有類名的String變量。 假設您有一個字符串列表,其中包含您要加載的所有類名(並使用靜態代碼塊自動注冊:
for(String className:classesToBeLoaded)Class.forName(className);
通過這個例子:
public class MainClass {
public static void main(String[] args){
ClassLoader classLoader = MainClass.class.getClassLoader();
try {
Class aClass = classLoader.loadClass("com.jenkov.MyClass");
System.out.println("aClass.getName() = " + aClass.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
如果您的類在文件系統中的jar中有可能(這可能聽起來很荒謬,但我看過從ldaps加載的類)
因此,如果您的類位於jar中的文件系統中,您可以執行以下操作:
下面的偽java:
String classPath = System.getClassPath();
String [] classPathParts = classpath.split(";"); // or :
String [] allTheClasses = []
for each ( file in classPathParts ) {
if( file is directory ) {
allTheClasses.addAll( file.contents );
} else if ( file is ".jar" ) {
allTheClasses.addAll( getZippedNamesFrom( file ) );
}
}
// At this point you would have all the classes in the array ( list ) .
String [] packageNames = {"a.b.c", "d.e.f" };
for each ( String clazzName in allTheClasses ) {
if ( packageNames.contains( clazzName.getPackageName() ) ) {
Class.forName( clazzName ); // load it and have the static block run
// Or run it your self
}
}
// End of the story.
我很久以前就做過類似的事情。
我用不到一秒鍾就可以使用這種方法加載大約70k +類名。 在我的情況下,我動態地尋找大約10個類,所以整個過程花了我大約1.1秒。
你可以使用ClassFinder
,
http://jmeter.apache.org/api/org/apache/jorphan/reflect/ClassFinder.html
我建議將所有“動態”類放入一個包中。 掃描該目錄以獲取每個文件名,然后在Class.forName()中使用它來加載和注冊每個類。
我昨天剛問了一個類似的問題,得到了一些很好的反饋。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.