我们这篇博文要做的事,就是将com.mec.study包下的类,都扫描显示出来。
写一个 Scanner.java类 用于实现扫描
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Enumeration;
public class Scanner
{
private static void dealClass(Class<?> klass)
{
}
private static void scanDirectory(File curFile, String packageName)
{
File[] files=curFile.listFiles();
for(File file : files)
{
// 如果是类的话
if(file.isFile())
{
String fileName=file.getName();
if(fileName.endsWith(".class"))
{
String className=packageName + "." + fileName.replace(".class", "");
System.out.println(className);
try
{
Class<?> klass=Class.forName(className);
dealClass(klass);
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
// 如果是包的话
else
{
// TODO 进入到下一层目录(包),递归扫描
}
// 缺乏分辨 包名 和 类名
// System.out.println(file.getName());// file.getName()
}
}
public static void main(String[] args)
{
String packageName="com.mec.Demo";
String packName=packageName.replace(".", "/");
System.out.println(packName);
// ClassLoader的具体作用就是将class文件加载到jvm虚拟机中去; 当前线程的类加载器
ClassLoader classLoader=Thread.currentThread().getContextClassLoader();
try
{
// 希望得到url(资源定位器)的集合,
Enumeration<URL> urls=classLoader.getResources(packName);// 导这个 import java.net.URL;
while(urls.hasMoreElements())
{
URL url=urls.nextElement();
File file=new File(url.toURI());
// TODO扫描file下的所有文件
scanDirectory(file, packageName);
// System.out.println(file.getName());
}
}
catch(IOException e)
{
e.printStackTrace();
}
catch(URISyntaxException e)
{
e.printStackTrace();
}
}
}
运行结果
我们可以将 包扫描 弄成专属于我们的工具包 PackageScanner.java ,就像xml解析工具那样。如下
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Enumeration;
public abstract class PackageScanner
{
public PackageScanner()
{
// TODO 自动生成的构造函数存根
}
public abstract void dealClass(Class<?> klass);
private void dealPackage(File cur, String packageName)
{
File[] files=cur.listFiles();
for(File file : files)
{
// 如果是类的话
if(file.isFile())
{
String fileName=file.getName();
if(!fileName.endsWith(".class"))
{
continue;
}
fileName=fileName.replace(".class", "");
String className=packageName + "." + fileName;
try
{
Class<?> klass=Class.forName(className);
dealClass(klass);
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
}
// 如果是包的话
else
{
// TODO 进入到下一层目录(包),递归扫描
dealPackage(file, packageName + "." + file.getName());
}
// 缺乏分辨 包名 和 类名
// System.out.println(file.getName());// file.getName()
}
}
public void scanPackage(String packageName)
{
// ClassLoader的具体作用就是将class文件加载到jvm虚拟机中去; 当前线程的类加载器
ClassLoader classLoader=Thread.currentThread().getContextClassLoader();
String packName=packageName.replace(".", "/");
try
{
// 希望得到url(资源定位器)的集合,
Enumeration<URL> urls=classLoader.getResources(packName);// 导这个 import java.net.URL;
while(urls.hasMoreElements())
{
URL url=urls.nextElement();
File curfile=new File(url.toURI());
// TODO扫描file下的所有文件
dealPackage(curfile, packageName);
// System.out.println(file.getName());
}
}
catch(IOException e)
{
e.printStackTrace();
}
catch(URISyntaxException e)
{
e.printStackTrace();
}
}
}
也给出一个使用我们这个工具类的 Test.java
public class Test
{
public static void main(String[] args)
{
new PackageScanner()
{
public void dealClass(Class<?> klass)
{
if(klass.isPrimitive() || klass.isInterface() || klass.isAnnotation() || klass.isArray() || klass.isEnum())
{
return;
}
System.out.println(klass.getName());
}
}.scanPackage("com.mec.study");
}
}
运行结果如下
上面是实现了我们自己写的包,那该如何扫描jar包呢
需要更改PackageScanner.java中的一点东西,如下
private void dealJar(URL url)
{
try
{
JarURLConnection connection=(JarURLConnection) url.openConnection();
JarFile jarFile=connection.getJarFile();
Enumeration<JarEntry> entryList=jarFile.entries();
while(entryList.hasMoreElements())
{
JarEntry jarEntry=entryList.nextElement();
if(jarEntry.isDirectory() || !jarEntry.getName().endsWith(".class"))
{
continue;
}
String className=jarEntry.getName();
className=className.replace(".class", " ");
className=className.replace("/", ".");
System.out.println(className);
// try
// {
// Class<?> klass=Class.forName(className);
// dealClass(klass);
// }
// catch(ClassNotFoundException e)
// {
// e.printStackTrace();
// }
}
}
catch(IOException e)
{
e.printStackTrace();
}
}
public void scanPackage(String packageName)
{
// ClassLoader的具体作用就是将class文件加载到jvm虚拟机中去; 当前线程的类加载器
ClassLoader classLoader=Thread.currentThread().getContextClassLoader();
String packName=packageName.replace(".", "/");
try
{
// 希望得到url(资源定位器)的集合,
Enumeration<URL> urls=classLoader.getResources(packName);// 导这个 import java.net.URL;
while(urls.hasMoreElements())
{
URL url=urls.nextElement();
if(url.getProtocol().equals("jar"))
{
dealJar(url);
}
else
{
File curfile;
try
{
curfile=new File(url.toURI());
// TODO扫描file下的所有文件
dealPackage(curfile, packageName);
// System.out.println(file.getName());
}
catch(URISyntaxException e)
{
e.printStackTrace();
}
}
}
}
catch(IOException e)
{
e.printStackTrace();
}
}