/**
* 测试
* @param args
*/
public static void main(String[] args) {
List<接口名> list = new ArrayList<>();
List<Class> clazzs = getAllInterfaceAchieveClass(接口名.class);
for(Class clazz : clazzs){
list.add((接口名)clazz.newInstance());
}
//打印Class对象
for(接口名 cla : list){
System.out.println("实现类:"+cla.getClass());
}
}
/**
* 获取所有接口的实现类
*
* @return
* @throws Throwable
*/
@SuppressWarnings("unchecked")
public List<Class> getAllInterfaceAchieveClass(Class clazz) throws Throwable {
ArrayList<Class> list = new ArrayList<>();
// 判断是否是接口
if (clazz.isInterface()) {
ArrayList<Class> allClass = getAllClassByPath(clazz.getPackage().getName());
/**
* 循环判断路径下的所有类是否实现了指定的接口 并且排除接口类自己
*/
for (int i = 0; i < allClass.size(); i++) {
// 排除抽象类
if (Modifier.isAbstract(allClass.get(i).getModifiers())) {
continue;
}
// 判断是不是同一个接口
if (clazz.isAssignableFrom(allClass.get(i))) {
if (!clazz.equals(allClass.get(i))) {
list.add(allClass.get(i));
}
}
}
}
return list;
}
/**
* 从指定路径下获取所有类
*
* @return
* @throws Throwable
*/
public ArrayList<Class> getAllClassByPath(String packagename) throws Throwable {
ArrayList<Class> list = new ArrayList<>();
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
String path = packagename.replace('.', '/');
ArrayList<File> fileList = new ArrayList<>();
Enumeration<URL> enumeration = classLoader.getResources(path);
while (enumeration.hasMoreElements()) {
URL url = enumeration.nextElement();
fileList.add(new File(url.getFile()));
}
for (int i = 0; i < fileList.size(); i++) {
list.addAll(findClass(fileList.get(i), packagename));
}
return list;
}
/**
* 如果file是文件夹,则递归调用findClass方法,或者文件夹下的类 如果file本身是类文件,则加入list中进行保存,并返回
*
* @param file
* @param packagename
* @return
* @throws ClassNotFoundException
*/
private ArrayList<Class> findClass(File file, String packagename) throws ClassNotFoundException {
ArrayList<Class> list = new ArrayList<>();
if (!file.exists()) {
return list;
}
File[] files = file.listFiles();
for (File file2 : files) {
if (file2.isDirectory()) {
assert !file2.getName().contains(".");// 添加断言用于判断
ArrayList<Class> arrayList = findClass(file2, packagename + "." + file2.getName());
list.addAll(arrayList);
} else if (file2.getName().endsWith(".class")) {
// 保存的类文件不需要后缀.class
list.add(Class.forName(packagename + '.' + file2.getName().substring(0, file2.getName().length() - 6)));
}
}
return list;
}
jar里找到包下所有实现类
/**
* 测试
* @param args
*/
public static void main(String[] args) {
List<接口名> list = new ArrayList<>();
List<Class> clazzs = getClasses(接口名.class);
for(Class clazz : clazzs){
list.add((接口名)clazz.newInstance());
}
//打印Class对象
for(接口名 cla : list){
System.out.println("实现类:"+cla.getClass());
}
}
/**
* 从包package中获取所有的Class
*
* @param pack
* @return
*/
public List<Class<?>> getClasses(Class clazz) {
List<Class<?>> list = new ArrayList<Class<?>>();
// 是否循环迭代
boolean recursive = true;
// 获取包的名字
String packageName = clazz.getPackage().getName();
String packageDirName = packageName.replace('.', '/');
Enumeration<URL> dirs;
try {
dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
// 循环迭代下去
while (dirs.hasMoreElements()) {
// 获取下一个元素
URL url = dirs.nextElement();
// 得到协议的名称
String protocol = url.getProtocol();
if ("jar".equals(protocol)) {
// 如果是jar包文件
// 定义一个JarFile
JarFile jar;
try {
JarURLConnection openConnection = (JarURLConnection) url.openConnection();
// 获取jar
jar = openConnection.getJarFile();
// 从此jar包 得到一个枚举类
Enumeration<JarEntry> entries = jar.entries();
// 同样的进行循环迭代
while (entries.hasMoreElements()) {
// 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件
JarEntry entry = entries.nextElement();
String name = entry.getName();
// 如果是以/开头的
if (name.charAt(0) == '/') {
// 获取后面的字符串
name = name.substring(1);
}
// 如果前半部分和定义的包名相同
if (name.startsWith(packageDirName)) {
int idx = name.lastIndexOf('/');
// 如果以"/"结尾 是一个包
if (idx != -1) {
// 获取包名 把"/"替换成"."
packageName = name.substring(0, idx).replace('/', '.');
}
// 如果可以迭代下去 并且是一个包
if ((idx != -1) || recursive) {
// 如果是一个.class文件 而且不是目录
if (name.endsWith(".class") && !entry.isDirectory()) {
// 去掉后面的".class" 获取真正的类名
String className = name.substring(packageName.length() + 1, name.length() - 6);
try {
// 添加到classes
list.add(Class.forName(packageName + '.' + className));
} catch (ClassNotFoundException e) {
// log.error("添加用户自定义视图类错误
// 找不到此类的.class文件");
e.printStackTrace();
}
}
}
}
}
} catch (IOException e) {
// log.error("在扫描用户定义视图时从jar包获取文件出错");
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
return list;
}