Я смешал ответы @Grodriguez и @bemace и добавил свою собственную стратегию, чтобы найти лучшее решение.Это решение имитирует во время выполнения функцию автоматического импорта, доступную во время компиляции.
Полный код Мое решение здесь .Для простого имени основными шагами являются:
- Получить список пакетов, доступных из текущего загрузчика классов.
- Для каждого пакета попробуйте загрузить полное имя, полученное из пакета+ простое имя.
Шаг 2 прост:
public List<String> getFQNs(String simpleName) {
if (this.packages == null) {
this.packages = getPackages();
}
List<String> fqns = new ArrayList<String>();
for (String aPackage : packages) {
try {
String fqn = aPackage + "." + simpleName;
Class.forName(fqn);
fqns.add(fqn);
} catch (Exception e) {
// Ignore
}
}
return fqns;
}
Шаг 1 сложнее и зависит от вашего приложения / среды, поэтому я реализовал различные стратегии для получения разных списков пакетов.
Текущий загрузчик классов (может быть полезно для обнаружения динамически генерируемых классов)
public Collection<String> getPackages() {
Set<String> packages = new HashSet<String>();
for (Package aPackage : Package.getPackages()) {
packages.add(aPackage.getName());
}
return packages;
}
Classpath (достаточно для приложений, которые полностью загруженыиз classpath. Не подходит для сложных приложений, таких как Eclipse)
public Collection<String> getPackages() {
String classpath = System.getProperty("java.class.path");
return getPackageFromClassPath(classpath);
}
public static Set<String> getPackageFromClassPath(String classpath) {
Set<String> packages = new HashSet<String>();
String[] paths = classpath.split(File.pathSeparator);
for (String path : paths) {
if (path.trim().length() == 0) {
continue;
} else {
File file = new File(path);
if (file.exists()) {
String childPath = file.getAbsolutePath();
if (childPath.endsWith(".jar")) {
packages.addAll(ClasspathPackageProvider
.readZipFile(childPath));
} else {
packages.addAll(ClasspathPackageProvider
.readDirectory(childPath));
}
}
}
}
return packages;
}
Bootstrap classpath (например, java.lang)
public Collection<String> getPackages() {
// Even IBM JDKs seem to use this property...
String classpath = System.getProperty("sun.boot.class.path");
return ClasspathPackageProvider.getPackageFromClassPath(classpath);
}
Eclipse связки (поставщик пакетов для конкретного домена)
// Don't forget to add "Eclipse-BuddyPolicy: global" to MANIFEST.MF
public Collection<String> getPackages() {
Set<String> packages = new HashSet<String>();
BundleContext context = Activator.getDefault().getBundle()
.getBundleContext();
Bundle[] bundles = context.getBundles();
PackageAdmin pAdmin = getPackageAdmin(context);
for (Bundle bundle : bundles) {
ExportedPackage[] ePackages = pAdmin.getExportedPackages(bundle);
if (ePackages != null) {
for (ExportedPackage ePackage : ePackages) {
packages.add(ePackage.getName());
}
}
}
return packages;
}
public PackageAdmin getPackageAdmin(BundleContext context) {
ServiceTracker bundleTracker = null;
bundleTracker = new ServiceTracker(context,
PackageAdmin.class.getName(), null);
bundleTracker.open();
return (PackageAdmin) bundleTracker.getService();
}
Примеры запросов и ответов в моей среде Eclipse:
- Файл: [java.io.File, org.eclipse.core.internal.resources.File]
- Список: [java.awt.List, org.eclipse.swt.widgets.List, com.sun.xml.internal.bind.v2.schemagen.xmlschema.List, java.util.List, org.hibernate.mapping..List]
- IResource: [org.eclipse.core.resources.IResource]