代码参考:http://blog.csdn.net/wangpeng047/article/details/8206427
我借用上面博客中的代码,把重点放在从file类型中获取类名,并增加了获取包含指定注解的类名的功能
代码获取的类名是诸如com.meso.nio.NIOClient这样的格式,可以直接运用于Class.forName(className)函数
import java.io.File;
import java.lang.annotation.Annotation;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class PackageUtil {
/**
* 从包下获取所有类名
*
* @param packageName
* 包名
* @return 包下的所有类名
*/
public static List<String> getClassNameByPackage(String packageName) {
return getClassName(packageName, true);
}
/**
* 从包下获取包含指定注解的所有类名
*
* @param packageName
* 包名
* @param annotation
* 注解类数组
* @return 包下的所有类名
*/
public static List<String> getClassNameByAnnotation(String packageName,
Class<? extends Annotation>... annotation) {
List<String> classNames = getClassName(packageName, true);
if (classNames != null) {
Iterator<String> it = classNames.iterator();
while (it.hasNext()) {
String className = it.next();
try {
Class<?> clasz = Class.forName(className);
boolean save = false;
for (Class<? extends Annotation> ann : annotation) {
if (clasz.isAnnotationPresent(ann)) {
save = true;
}
}
if (!save) {
it.remove();
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return classNames;
}
/**
* 从包下获取所有类名(供类内使用)
*
* @param packageName
* 包名
* @param childPackage
* 是否遍历子包
* @return 包下的所有类名
*/
@SuppressWarnings("deprecation")
private static List<String> getClassName(String packageName,
boolean childPackage) {
List<String> fileNames = null;
ClassLoader loader = Thread.currentThread().getContextClassLoader();
String packagePath = packageName.replace(".", "/");
URL url = loader.getResource(packagePath);
if (url != null) {
String type = url.getProtocol();
if (type.equals("file")) {
fileNames = getClassNameByFile(packageName,
URLDecoder.decode(url.getPath()), null, childPackage);
} else {
return null;
}
} else {
return null;
}
return fileNames;
}
/**
* 从项目文件获取某包下所有类(供类内使用)
*
* @param filePath
* 文件路径
* @param className
* 类名集合
* @param childPackage
* 是否遍历子包
* @return 类的完整名称
*/
private static List<String> getClassNameByFile(String packageName,
String filePath, List<String> className, boolean childPackage) {
List<String> myClassName = new ArrayList<String>();
File file = new File(filePath.substring(1));
File[] childFiles = file.listFiles();
for (File childFile : childFiles) {
if (childFile.isDirectory()) {
if (childPackage) {
myClassName.addAll(getClassNameByFile(packageName,
childFile.getPath(), myClassName, childPackage));
}
} else {
String childFilePath = childFile.getPath();
if (childFilePath.endsWith(".class")) {
childFilePath = childFilePath.substring(0,
childFilePath.length() - 6);
int lastIndex = childFilePath.lastIndexOf('\\');
if (lastIndex == -1) {
myClassName.add(packageName + "." + childFilePath);
} else {
myClassName.add(packageName + "."
+ childFilePath.substring(lastIndex + 1));
}
}
}
}
return myClassName;
}
}