如何反射一个包下的所有类到一个List<Class<?>> 本帖最后由 yeqi3000 于 2014-02-25 10:49:49 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 反射一般都是反射类,如果要反射包,可能要自己写了。你可以先获得包名,如class.getPackage(),然后用File类获取所有的类名,然后再去反射试试。 import java.util.ArrayList;import java.util.List;public class IoTest { /** * @param args */ @SuppressWarnings("unchecked") public static void main(String[] args) { // 创建list @SuppressWarnings("rawtypes") List list = new ArrayList(); try { // 通过反射实例化对象,并添加入list中 Object o1 = Class.forName("A").newInstance(); Object o2 = Class.forName("B").newInstance(); Object o3 = Class.forName("C").newInstance(); list.add(o1); list.add(o2); list.add(o3); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } // 使用list for (Object o : list) { if (o instanceof A) { System.out.println("This is A"); } if (o instanceof B) { System.out.println("This is B"); } if (o instanceof C) { System.out.println("This is C"); } } }}不知道是不是楼主想要的楼主有点表述不清 我按照http://bbs.csdn.net/topics/330125949这个帖子里的代码写,出现这个错误: 我之前也想做同样的事,发现 Java 好像没有提供这种支持,所以应该没有简单干净的实现方法。ClassLoader 的工作原则是,当你特别指定某一个 qualified class name 的时候才去寻找或加载那个类,而对于“目前已经加载”的类,也不提供类似基于包名的迭代查询。一种思路是想办法获取当前运行的 jvm 的 classpath 参数,然后去文件系统检查 classpath 范围内所有的 class 文件,很脏,很费时,而且得到的结果只是某包名下“所有可能被加载的类”。要得到“已经加载的类中属于某包名的那些”,没什么思路,应该是做不到的。——话虽如此,如果用了自定义的ClassLoader,那当然可以提供功能查询“该ClassLoader下所有属于某包名的类”。 补充:刚刚搜了一下,发现还是有(虽然有点hacky)办法在不影响某类加载与否的前提下检查“某类是否已经加载”,这是我之前不知道的 :-)http://stackoverflow.com/questions/3678579/how-to-check-whether-a-class-is-initialized 思路:通过包名得到文件夹路劲。通过File类列出所有文件。再根据包名+文件名进行反射 楼主可以看看https://code.google.com/p/reflections/ 怎么通过包名得到文件夹路径?包名是:com.Models在安卓下怎么获取其路径? 版主,你这样是不行的!------------------楼主: 你的要求未必办得到。理由: 首先、你要理解是什么Java反射? 其次、Java在什么情况下提供反射?答:很显然,只有被加载的类,才可能提供其class交付给运行时,此时才能反射!也就是说,你的包中,如果类未被加载,何来反射?-----------------解决方案:IO流查找关键字,比如,你要查找List,关键字List,等等 ... 围观遍历java下所有的类的方法 刚上手安卓开发,java才用了2周,能给详细代码不? 下载了那个jar并添加到了libs,并引用,按上面的示例写了代码,但放安卓一运行就异常,程序崩溃了。 这没什么难的吧,就一个先序遍历:import java.io.File;import java.io.IOException;import java.util.ArrayList;import java.util.List;public class ScanPackage {/** *遍历包 并遍历子包 */public static void scan(String packageName ,List<Class<?>> list) throws Exception{ String path=getSrcPath()+packageToDir(packageName); File dir=new File(path); File[] files=dir.listFiles(); Class<?> cla=null; for(File f:files){ if(f.isDirectory()){ String childName=packageName+"."+f.getName(); scan(childName, list); }else{ cla=Class.forName(packageName+"."+f.getName().split("\\.")[0]); list.add(cla); } }}/**获取当前路径*/public static String getSrcPath() throws IOException{ File file=new File(""); String path=file.getCanonicalPath()+File.separator+"src"; return path;}/** *package转换为路径格式 */public static String packageToDir(String packageName){ String[] array=packageName.split("\\."); StringBuffer sb=new StringBuffer(); for(String str:array){ sb.append(File.separator).append(str); } return sb.toString();}public static void main(String[] args) throws Exception { List<Class<?>> list=new ArrayList<Class<?>>(); scan("com.Models",list); System.out.println(list.size()); for(Class<?> cla:list){ System.out.println(cla.getName()); }}} 使用你这个打包到安卓软件发布后,调试时发现File[] files=dir.listFiles();执行后,files为null 那应该就是31行的函数的问题:String path=file.getCanonicalPath()+File.separator+"src";这个函数在Eclipse中是正确的,可能不支持android系统;你找找android中有没有类似于"获取当前路径"之类的函数。 /** * 从一个包中找出所有的类,不包括jar包 * @param packageName * @return * @throws IOException * @throws ClassNotFoundException */ @SuppressWarnings("rawtypes") public static List<Class> getClasses(String packageName) throws IOException, ClassNotFoundException { ClassLoader classLoader = Thread.currentThread() .getContextClassLoader(); String path = packageName.replace(".", "/"); System.out.println("Path:"+path); Enumeration<URL> resources = classLoader.getResources(path); List<File> dirs = new ArrayList<File>(); while (resources.hasMoreElements()) { URL urlResource = resources.nextElement(); dirs.add(new File(urlResource.getFile())); } List<Class> classes = new ArrayList<Class>(); for (File directory : dirs) { classes.addAll(findClasses(directory, packageName)); } return classes; } @SuppressWarnings("rawtypes") private static List<Class> findClasses(File directory, String packageName) throws ClassNotFoundException { List<Class> classes=new ArrayList<Class>(); if(!directory.isDirectory()){ return classes; } File[] files=directory.listFiles(); for(File file:files){ if(file.isDirectory()){ assert !file.getName().contains("."); System.out.println(packageName+"."+file.getName()); classes.addAll(findClasses(file,packageName+"."+file.getName())); }else if(file.getName().endsWith(".class")){ classes.add(Class.forName(packageName+"."+file.getName().substring(0, file.getName().length()-6))); } } return classes; } 我想知道 spring中自动扫描包下所有带注解的类是怎么做到的啊 自己解析遍历jar文件,取得包名+classname,然后反射取得想要的属性。 既然文件路径有了,比如com/isoft/dao/UserDao.java,那么就有com.iosft.dao.UserDao.java,然后就能用Class.forName()取得Class,接着用getAnnotations()取得注解数组,看看里边是否有@Component,如果有的话,就添加到上下文当中 paint(graphics g) 参数传递 Java 动态代理 这样配置就能使用到,连接池吗?关于Spring配置proxool 初学JAVA,做个什么程序来锻炼一下呢?请各位有经验的朋友提个建议! 关于Set的程序,为什么编译出错? HELP...... 请问怎样把double转换为String stringbuffer 删除最后一个=号之前的文字 utf-8编码转成GBK,难道我们真的束手无策了吗?? JB老是自做聰明的把中文輸入法調出來,﹐怎麼解決這個問題? 怎么解析很长的字符串 求高手解答java内部类问题
import java.util.ArrayList;
import java.util.List;public class IoTest { /**
* @param args
*/
@SuppressWarnings("unchecked")
public static void main(String[] args) {
// 创建list
@SuppressWarnings("rawtypes")
List list = new ArrayList(); try {
// 通过反射实例化对象,并添加入list中
Object o1 = Class.forName("A").newInstance();
Object o2 = Class.forName("B").newInstance();
Object o3 = Class.forName("C").newInstance();
list.add(o1);
list.add(o2);
list.add(o3);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} // 使用list
for (Object o : list) {
if (o instanceof A) {
System.out.println("This is A");
}
if (o instanceof B) {
System.out.println("This is B");
}
if (o instanceof C) {
System.out.println("This is C");
}
}
}}不知道是不是楼主想要的
楼主有点表述不清
补充:刚刚搜了一下,发现还是有(虽然有点hacky)办法在不影响某类加载与否的前提下检查“某类是否已经加载”,这是我之前不知道的 :-)http://stackoverflow.com/questions/3678579/how-to-check-whether-a-class-is-initialized
通过包名得到文件夹路劲。
通过File类列出所有文件。再根据包名+文件名进行反射
包名是:com.Models
在安卓下怎么获取其路径?
版主,你这样是不行的!
------------------
楼主:
你的要求未必办得到。
理由:
首先、你要理解是什么Java反射?
其次、Java在什么情况下提供反射?
答:很显然,只有被加载的类,才可能提供其class交付给运行时,此时才能反射!
也就是说,你的包中,如果类未被加载,何来反射?
-----------------
解决方案:IO流查找关键字,比如,你要查找List,关键字List,等等 ...
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;public class ScanPackage {
/**
*遍历包 并遍历子包
*/
public static void scan(String packageName ,List<Class<?>> list) throws Exception{
String path=getSrcPath()+packageToDir(packageName);
File dir=new File(path);
File[] files=dir.listFiles();
Class<?> cla=null;
for(File f:files){
if(f.isDirectory()){
String childName=packageName+"."+f.getName();
scan(childName, list); }else{
cla=Class.forName(packageName+"."+f.getName().split("\\.")[0]);
list.add(cla);
}
}
}
/**
获取当前路径
*/
public static String getSrcPath() throws IOException{
File file=new File("");
String path=file.getCanonicalPath()+File.separator+"src";
return path;
}
/**
*package转换为路径格式
*/
public static String packageToDir(String packageName){
String[] array=packageName.split("\\.");
StringBuffer sb=new StringBuffer();
for(String str:array){
sb.append(File.separator).append(str);
}
return sb.toString();
}
public static void main(String[] args) throws Exception {
List<Class<?>> list=new ArrayList<Class<?>>();
scan("com.Models",list);
System.out.println(list.size());
for(Class<?> cla:list){
System.out.println(cla.getName());
}
}
}
File[] files=dir.listFiles();
执行后,files为null
* 从一个包中找出所有的类,不包括jar包
* @param packageName
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
@SuppressWarnings("rawtypes")
public static List<Class> getClasses(String packageName)
throws IOException, ClassNotFoundException {
ClassLoader classLoader = Thread.currentThread()
.getContextClassLoader();
String path = packageName.replace(".", "/");
System.out.println("Path:"+path);
Enumeration<URL> resources = classLoader.getResources(path);
List<File> dirs = new ArrayList<File>();
while (resources.hasMoreElements()) {
URL urlResource = resources.nextElement();
dirs.add(new File(urlResource.getFile()));
}
List<Class> classes = new ArrayList<Class>();
for (File directory : dirs) {
classes.addAll(findClasses(directory, packageName));
}
return classes;
} @SuppressWarnings("rawtypes")
private static List<Class> findClasses(File directory, String packageName) throws ClassNotFoundException {
List<Class> classes=new ArrayList<Class>();
if(!directory.isDirectory()){
return classes;
}
File[] files=directory.listFiles();
for(File file:files){
if(file.isDirectory()){
assert !file.getName().contains(".");
System.out.println(packageName+"."+file.getName());
classes.addAll(findClasses(file,packageName+"."+file.getName()));
}else if(file.getName().endsWith(".class")){
classes.add(Class.forName(packageName+"."+file.getName().substring(0, file.getName().length()-6)));
}
}
return classes;
}