Java中如何不依赖第三方库自动获取并实例化指定类的所有子类
纯JDK实现自动实例化所有City子类
你给出的类定义存在基础语法错误,先修正:class关键字首字母不需要大写,所有城市子类需要显式继承City抽象类,修正后基础代码如下:
public abstract class City { public abstract String getName(); } public class London extends City { @Override public String getName() { return "London"; } } public class Paris extends City { @Override public String getName() { return "Paris"; } }
不依赖任何第三方库的实现思路是通过类加载器扫描指定包下的所有字节码文件,筛选出City的非抽象子类,再通过反射调用无参构造完成实例化,完整代码如下:
import java.io.File; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Objects; public class CityAutoLoader { public static List<City> loadAllCities(String basePackage) throws Exception { List<City> result = new ArrayList<>(); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); String packagePath = basePackage.replace('.', '/'); URL resource = classLoader.getResource(packagePath); if (resource == null) { return result; } File packageDir = new File(resource.toURI()); // 遍历包下所有class文件 for (File file : Objects.requireNonNull(packageDir.listFiles())) { String fileName = file.getName(); if (!fileName.endsWith(".class")) { continue; } // 加载类 String className = basePackage + "." + fileName.substring(0, fileName.length() - 6); Class<?> clazz = Class.forName(className); // 校验是否为City的可实例化子类:非抽象、非接口、不是City类本身 if (City.class.isAssignableFrom(clazz) && !clazz.isInterface() && !java.lang.reflect.Modifier.isAbstract(clazz.getModifiers()) && !clazz.equals(City.class)) { // 反射调用无参构造实例化 City cityInstance = (City) clazz.getDeclaredConstructor().newInstance(); result.add(cityInstance); } } return result; } // 测试调用 public static void main(String[] args) throws Exception { // 替换为你项目中存放City类和子类的实际包路径 List<City> cities = loadAllCities("com.example.demo.cities"); cities.forEach(city -> System.out.println(city.getName())); } }
注意事项
- 所有
City子类必须保留public无参构造方法,和你手动new子类时的调用前提一致 - 如果你的子类分布在多个子包下,只需要给文件遍历逻辑补充递归处理子目录的代码即可覆盖所有路径
- 上述实现完全使用JDK原生API,没有引入任何外部第三方依赖
内容的提问来源于stack exchange,提问作者noob
相关产品推荐
相关产品推荐

