本篇内容主要讲解“如何用Java反射获取包下所有类”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何用Java反射获取包下所有类”吧!

我就废话不多说了,大家还是直接看代码吧~

/***根据包名获取包下面所有的类名**@parampack*@return*@throwsException*/publicstaticSet<Class<?>>getClasses(Stringpack)throwsException{//第一个class类的集合Set<Class<?>>classes=newLinkedHashSet<Class<?>>();//是否循环迭代booleanrecursive=true;//获取包的名字并进行替换StringpackageName=pack;StringpackageDirName=packageName.replace('.','/');//定义一个枚举的集合并进行循环来处理这个目录下的thingsEnumeration<URL>dirs;try{dirs=Thread.currentThread().getContextClassLoader().getResources(packageDirName);//循环迭代下去while(dirs.hasMoreElements()){//获取下一个元素URLurl=dirs.nextElement();//得到协议的名称Stringprotocol=url.getProtocol();//如果是以文件的形式保存在服务器上if("file".equals(protocol)){//获取包的物理路径StringfilePath=URLDecoder.decode(url.getFile(),"UTF-8");//以文件的方式扫描整个包下的文件并添加到集合中findClassesInPackageByFile(packageName,filePath,recursive,classes);}elseif("jar".equals(protocol)){//如果是jar包文件//定义一个JarFileSystem.out.println("jar类型的扫描");JarFilejar;try{//获取jarjar=((JarURLConnection)url.openConnection()).getJarFile();//从此jar包得到一个枚举类Enumeration<JarEntry>entries=jar.entries();findClassesInPackageByJar(packageName,entries,packageDirName,recursive,classes);}catch(IOExceptione){//log.error("在扫描用户定义视图时从jar包获取文件出错");e.printStackTrace();}}}}catch(IOExceptione){e.printStackTrace();}returnclasses;}

/***以文件的形式来获取包下的所有Class**@parampackageName*@parampackagePath*@paramrecursive*@paramclasses*/privatestaticvoidfindClassesInPackageByFile(StringpackageName,StringpackagePath,finalbooleanrecursive,Set<Class<?>>classes){//获取此包的目录建立一个FileFiledir=newFile(packagePath);//如果不存在或者也不是目录就直接返回if(!dir.exists()||!dir.isDirectory()){//log.warn("用户定义包名"+packageName+"下没有任何文件");return;}//如果存在就获取包下的所有文件包括目录File[]dirfiles=dir.listFiles(newFileFilter(){//自定义过滤规则如果可以循环(包含子目录)或则是以.class结尾的文件(编译好的java类文件)@Overridepublicbooleanaccept(Filefile){return(recursive&&file.isDirectory())||(file.getName().endsWith(".class"));}});//循环所有文件for(Filefile:dirfiles){//如果是目录则继续扫描if(file.isDirectory()){findClassesInPackageByFile(packageName+"."+file.getName(),file.getAbsolutePath(),recursive,classes);}else{//如果是java类文件去掉后面的.class只留下类名StringclassName=file.getName().substring(0,file.getName().length()-6);try{//添加到集合中去//classes.add(Class.forName(packageName+'.'+//className));//经过回复同学的提醒,这里用forName有一些不好,会触发static方法,没有使用classLoader的load干净classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName+'.'+className));}catch(ClassNotFoundExceptione){//log.error("添加用户自定义视图类错误找不到此类的.class文件");e.printStackTrace();}}}}

/***以jar的形式来获取包下的所有Class**@parampackageName*@paramentries*@parampackageDirName*@paramrecursive*@paramclasses*/privatestaticvoidfindClassesInPackageByJar(StringpackageName,Enumeration<JarEntry>entries,StringpackageDirName,finalbooleanrecursive,Set<Class<?>>classes){//同样的进行循环迭代while(entries.hasMoreElements()){//获取jar里的一个实体可以是目录和一些jar包里的其他文件如META-INF等文件JarEntryentry=entries.nextElement();Stringname=entry.getName();//如果是以/开头的if(name.charAt(0)=='/'){//获取后面的字符串name=name.substring(1);}//如果前半部分和定义的包名相同if(name.startsWith(packageDirName)){intidx=name.lastIndexOf('/');//如果以"/"结尾是一个包if(idx!=-1){//获取包名把"/"替换成"."packageName=name.substring(0,idx).replace('/','.');}//如果可以迭代下去并且是一个包if((idx!=-1)||recursive){//如果是一个.class文件而且不是目录if(name.endsWith(".class")&&!entry.isDirectory()){//去掉后面的".class"获取真正的类名StringclassName=name.substring(packageName.length()+1,name.length()-6);try{//添加到classesclasses.add(Class.forName(packageName+'.'+className));}catch(ClassNotFoundExceptione){//.error("添加用户自定义视图类错误找不到此类的.class文件");e.printStackTrace();}}}}}}

补充:通过java反射机制获取该类的所有属性类型、值、

方法使用了这俩个包下的 field 和method

importjava.lang.reflect.Field;importjava.lang.reflect.Method;

publicstaticvoidgetObjectValue(Objectobject)throwsException{//我们项目的所有实体类都继承BaseDomain(所有实体基类:该类只是串行化一下)//不需要的自己去掉即可if(object!=null&&objectinstanceofBaseDomain){//if(object!=null)----begin//拿到该类Class<?>clz=object.getClass();//获取实体类的所有属性,返回Field数组Field[]fields=clz.getDeclaredFields();for(Fieldfield:fields){//--for()beginSystem.out.println(field.getGenericType());//打印该类的所有属性类型//如果类型是Stringif(field.getGenericType().toString().equals("classjava.lang.String")){//如果type是类类型,则前面包含"class",后面跟类名//拿到该属性的gettet方法/***这里需要说明一下:他是根据拼凑的字符来找你写的getter方法的*在Boolean值的时候是isXXX(默认使用ide生成getter的都是isXXX)*如果出现NoSuchMethod异常就说明它找不到那个gettet方法需要做个规范*/Methodm=(Method)object.getClass().getMethod("get"+getMethodName(field.getName()));Stringval=(String)m.invoke(object);//调用getter方法获取属性值if(val!=null){System.out.println("Stringtype:"+val);}}//如果类型是Integerif(field.getGenericType().toString().equals("classjava.lang.Integer")){Methodm=(Method)object.getClass().getMethod("get"+getMethodName(field.getName()));Integerval=(Integer)m.invoke(object);if(val!=null){System.out.println("Integertype:"+val);}}//如果类型是Doubleif(field.getGenericType().toString().equals("classjava.lang.Double")){Methodm=(Method)object.getClass().getMethod("get"+getMethodName(field.getName()));Doubleval=(Double)m.invoke(object);if(val!=null){System.out.println("Doubletype:"+val);}}//如果类型是Boolean是封装类if(field.getGenericType().toString().equals("classjava.lang.Boolean")){Methodm=(Method)object.getClass().getMethod(field.getName());Booleanval=(Boolean)m.invoke(object);if(val!=null){System.out.println("Booleantype:"+val);}}//如果类型是boolean基本数据类型不一样这里有点说名如果定义名是isXXX的那就全都是isXXX的//反射找不到getter的具体名if(field.getGenericType().toString().equals("boolean")){Methodm=(Method)object.getClass().getMethod(field.getName());Booleanval=(Boolean)m.invoke(object);if(val!=null){System.out.println("booleantype:"+val);}}//如果类型是Dateif(field.getGenericType().toString().equals("classjava.util.Date")){Methodm=(Method)object.getClass().getMethod("get"+getMethodName(field.getName()));Dateval=(Date)m.invoke(object);if(val!=null){System.out.println("Datetype:"+val);}}//如果类型是Shortif(field.getGenericType().toString().equals("classjava.lang.Short")){Methodm=(Method)object.getClass().getMethod("get"+getMethodName(field.getName()));Shortval=(Short)m.invoke(object);if(val!=null){System.out.println("Shorttype:"+val);}}//如果还需要其他的类型请自己做扩展}//for()--end}//if(object!=null)----end}//把一个字符串的第一个字母大写、效率是最高的、privatestaticStringgetMethodName(StringfildeName)throwsException{byte[]items=fildeName.getBytes();items[0]=(byte)((char)items[0]-'a'+'A');returnnewString(items);}

到此,相信大家对“如何用Java反射获取包下所有类”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!