[Java]
Package com. itkt. mtravel. hotel. util;
Import java. io. File;
Import java.net. URL;
Import java.net. URLClassLoader;
Import java. util. ArrayList;
Import java. util. Enumeration;
Import java. util. List;
Import java. util. jar. JarEntry;
Import java. util. jar. JarFile;
Public class PackageUtil {
Public static void main (String [] args) throws Exception {
String packageName = "com. wang. vo. request. hotel ";
// List <String> classNames = getClassName (packageName );
List <String> classNames = getClassName (packageName, false );
If (classNames! = Null ){
For (String className: classNames ){
System. out. println (className );
}
}
}
/**
* Obtain all classes under a certain package (including all sub-packages of this package)
* @ Param packageName package name
* @ Return full name of the class
*/
Public static List <String> getClassName (String packageName ){
Return getClassName (packageName, true );
}
/**
* Obtain all classes in a package
* @ Param packageName package name
* @ Param childPackage whether to traverse the sub-Package
* @ Return full name of the class
*/
Public static List <String> getClassName (String packageName, boolean childPackage ){
List <String> fileNames = null;
ClassLoader loader = Thread. currentThread (). getContextClassLoader ();
String packagePath = packageName. replace (".","/");
URL url = loader. getResource (packagePath );
If (url! = Null ){
String type = url. getProtocol ();
If (type. equals ("file ")){
FileNames = getClassNameByFile (url. getPath (), null, childPackage );
} Else if (type. equals ("jar ")){
FileNames = getClassNameByJar (url. getPath (), childPackage );
}
} Else {
FileNames = getClassNameByJars (URLClassLoader) loader). getURLs (), packagePath, childPackage );
}
Return fileNames;
}
/**
* Retrieve all classes under a certain package from the project file
* @ Param filePath: file path
* @ Param className class name set
* @ Param childPackage whether to traverse the sub-Package
* @ Return full name of the class
*/
Private static List <String> getClassNameByFile (String filePath, List <String> className, boolean childPackage ){
List <String> myClassName = new ArrayList <String> ();
File file = new File (filePath );
File [] childFiles = file. listFiles ();
For (File childFile: childFiles ){
If (childFile. isDirectory ()){
If (childPackage ){
MyClassName. addAll (getClassNameByFile (childFile. getPath (), myClassName, childPackage ));
}
} Else {
String childFilePath = childFile. getPath ();
If (childFilePath. endsWith (". class ")){
ChildFilePath = childFilePath. substring (childFilePath. indexOf ("\ classes") + 9, childFilePath. lastIndexOf ("."));
ChildFilePath = childFilePath. replace ("\\",".");
MyClassName. add (childFilePath );
}
}
}
Return myClassName;
}
/**
* Obtain all classes in a package from jar.
* @ Param jarPath: jar file path
* @ Param childPackage whether to traverse the sub-Package
* @ Return full name of the class
*/
Private static List <String> getClassNameByJar (String jarPath, boolean childPackage ){
List <String> myClassName = new ArrayList <String> ();
String [] jarInfo = jarPath. split ("! ");
String jarFilePath = jarInfo [0]. substring (jarInfo [0]. indexOf ("/"));
String packagePath = jarInfo [1]. substring (1 );
Try {
JarFile jarFile = new JarFile (jarFilePath );
Enumeration <JarEntry> entrys = jarFile. entries ();
While (entrys. hasMoreElements ()){
JarEntry jarEntry = entrys. nextElement ();
String entryName = jarEntry. getName ();
If (entryName. endsWith (". class ")){
If (childPackage ){
If (entryName. startsWith (packagePath )){
EntryName = entryName. replace ("/", "."). substring (0, entryName. lastIndexOf ("."));
MyClassName. add (entryName );
}
} Else {
Int index = entryName. lastIndexOf ("/");
String myPackagePath;
If (index! =-1 ){
MyPackagePath = entryName. substring (0, index );
} Else {
MyPackagePath = entryName;
}
If (myPackagePath. equals (packagePath )){
EntryName = entryName. replace ("/", "."). substring (0, entryName. lastIndexOf ("."));
MyClassName. add (entryName );
}
}
}
}
} Catch (Exception e ){
E. printStackTrace ();
}
Return myClassName;
}
/**
* Search for the package from all jar files and obtain all classes in the package.
* @ Param urls URL set
* @ Param packagePath package path
* @ Param childPackage whether to traverse the sub-Package
* @ Return full name of the class
*/
Private static List <String> getClassNameByJars (URL [] urls, String packagePath, boolean childPackage ){
List <String> myClassName = new ArrayList <String> ();
If (urls! = Null ){
For (int I = 0; I <urls. length; I ++ ){
URL url = urls [I];
String urlPath = url. getPath ();
// You do not need to search for the classes folder
If (urlPath. endsWith ("classes /")){
Continue;
}
String jarPath = urlPath + "! /"+ PackagePath;
MyClassName. addAll (getClassNameByJar (jarPath, childPackage ));
}
}
Return myClassName;
}
}
Because we are not sure which method is used to generate the jar package, if we use the default jar package generation method, we use the Thread. currentThread (). getContextClassLoader (). getResource () cannot be obtained, so I added the package domain name to search for all jar packages, which improves the function a lot.
Then, the "How to traverse all classes in the package" is over, and the functionality of the PackageUtil class is still a little small. Further improvement may not be ruled out, if you have any new requirements or suggestions about this util, you are welcome to submit it at any time. If any bug is found, please notify me in time for improvement.