在java中检测具有特定注释的所有类
我正在制作一个应用程序,该应用程序运行具有@Window注释的类中的所有方法,但目前我有以下内容:在java中检测具有特定注释的所有类,java,Java,我正在制作一个应用程序,该应用程序运行具有@Window注释的类中的所有方法,但目前我有以下内容: Class<App> obj = App.class; Object t = null; try { t = obj.newInstance(); } catch (Exception e) { e.printStackTrace(); } if (obj.isAnnotationPresent(Wind
Class<App> obj = App.class;
Object t = null;
try {
t = obj.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
if (obj.isAnnotationPresent(Window.class)) {
for (Method method : obj.getMethods()) {
if (method.isAnnotationPresent(Window.Run.class)) {
try {
method.invoke(t, new Object[] {});
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}
}
Class obj=App.Class;
对象t=null;
试一试{
t=obj.newInstance();
}捕获(例外e){
e、 printStackTrace();
}
if(对象isAnnotationPresent(窗口类)){
for(方法:obj.getMethods()){
if(方法.isAnnotationPresent(Window.Run.class)){
试一试{
调用(t,新对象[]{});
}捕获(例外e){
System.err.println(e.getMessage());
}
}
}
}
但只有我知道类名,它才能工作。在没有外部API的情况下,如何检测项目中的所有类?我认为没有一种非常简单的方法可以做到这一点,或者事实上,即使创建自己的自定义实现是值得的 我不明白为什么您不想使用外部依赖来实现这一点。几个月前我遇到了同样的问题,我只是选择使用reflections API来完成我的工作。您可以在此查看更多信息: 除此之外,您还可以考虑创建一个实用程序,该实用程序将扫描项目的各个包,寻找用该注释注释的类和方法,但正如前面提到的,这将导致您创建类似于上面提到的库的东西 除此之外,您还可以研究注释后处理器(这是您自己创建的),但我没有尝试过这种方法,也不能告诉您是否符合您的要求
底线是,除非有一个非常严格的需求要求您不能使用第三方库,否则我看不出有任何理由要求您重新发明轮子。所以是的,这很困难,但我没有任何API
private static List<Class<?>> findClasses(File directory, String packageName) {
List<Class<?>> classes = new ArrayList<Class<?>>();
if (!directory.exists())
return classes;
File[] files = directory.listFiles();
for (File file : files) {
if (file.isDirectory()) {
assert !file.getName().contains(".");
classes.addAll(findClasses(file,
(!packageName.equals("") ? packageName + "." : packageName) + file.getName()));
} else if (file.getName().endsWith(".class"))
try {
classes.add(Class
.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6)));
} catch (ClassNotFoundException e) {
System.err.println(e.getMessage());
}
}
return classes;
}
private static List>classes=new ArrayList[]getClasses(字符串packageName){
ClassLoader ClassLoader=Thread.currentThread().getContextClassLoader();
断言类加载器!=null;
字符串路径=packageName.replace('.','/');
枚举资源=null;
试一试{
resources=classLoader.getResources(路径);
}捕获(IOE异常){
System.err.println(e.getMessage());
}
List dirs=new ArrayList();
while(resources.hasMoreElements()){
URL resource=resources.nextElement();
添加(新文件(resource.getFile());
}
列表>();
for(文件目录:dirs)
addAll(findClasses(目录,packageName));
返回classes.toArray(新类[classes.size()]);
}
然后这个方法使用findClasses()方法从包中提取所有类。您可以在这里查看:@Frighi是的,我已经看到了,但是它使用外部API,没有问题。我只是想在没有它们的情况下重新创建它。@Frighi,但显然没有简单的方法,所以我可能会使用它。我看不出有任何理由对此投反对票。
public static Class<?>[] getClasses(String packageName) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
assert classLoader != null;
String path = packageName.replace('.', '/');
Enumeration<URL> resources = null;
try {
resources = classLoader.getResources(path);
} catch (IOException e) {
System.err.println(e.getMessage());
}
List<File> dirs = new ArrayList<File>();
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
dirs.add(new File(resource.getFile()));
}
List<Class<?>> classes = new ArrayList<Class<?>>();
for (File directory : dirs)
classes.addAll(findClasses(directory, packageName));
return classes.toArray(new Class[classes.size()]);
}