欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

从jar包中搜寻拥有某个方法的所有class

程序员文章站 2022-05-13 09:17:40
...

看到一个问题,"一个jar包有很多的class,但是,唯一知道的只是一个方法名,怎么样知道哪一个或哪些class拥有这个方法呢?"

我想我们可以通过如下的步骤来实现:

1. 获取jar包中所有的JarEntry
2. 检查每一个JarEntry的name,如果name是以'.class'结尾,那么,获取class名字
3. 使用第2步中得到的class名字,通过反射获取Method数组。
4. 循环Method数组,如果发现方法名与已知的方法名一致,则在控制台输出该类的class name。

基于上述思想,我写了一个小程序,并去跑了一个实例--> 在jar包 'commons-lang-2.4.jar'中查找拥有方法名 'removeCauseMethodName' 的class。

控制台输出的结果如下:
Method [removeCauseMethodName] is included in Class [org.apache.commons.lang.exception.ExceptionUtils]

具体的代码如下:

注意: 运行如下程序之前请先把'commons-lang-2.4.jar' 添加到build path中,然后根据自己的workspace环境指定该jar包的具体路径。

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class SearchMetodInJarFile {

	private static final String CLASS_SUFFIX = ".class";

	public static void main(String[] args) throws IOException,
			SecurityException, ClassNotFoundException {

		/** target method name to be searched */
		String targetMethodClass = "removeCauseMethodName";

		/**
		 * Specify a target method name as 'removeCauseMethodName'. Find class
		 * name that includes the target method name in Jar File.
		 */
		new SearchMetodInJarFile().searchMethodName(new JarFile(
				"D:\\Develop\\workspace\\Test\\commons-lang-2.4.jar"),
				targetMethodClass);

	}

	/**
	 * Search target method name in multiple Jar files.
	 */
	public void searchMethodName(JarFile[] jarFiles, String targetMethodName)
			throws SecurityException, ClassNotFoundException {

		for (JarFile jarFile : jarFiles) {
			searchMethodName(jarFile, targetMethodName);
		}
	}

	/**
	 * Search target method name in one Jar file.
	 */
	public void searchMethodName(JarFile jarFile, String targetMethodName)
			throws SecurityException, ClassNotFoundException {
		Enumeration<JarEntry> entryEnum = jarFile.entries();
		while (entryEnum.hasMoreElements()) {
			doSearchMethodName(entryEnum.nextElement(), targetMethodName);
		}
	}

	/**
	 * Check the name of JarEntry, if its name ends with '.class'. Then do the
	 * following 3 steps: 1. Populate Class name. 2. Get the methods by
	 * reflection. 3. Compare the target method name with the names. If the
	 * methood name is equal to target method name. Then print the method name
	 * and class name in console.
	 */
	private void doSearchMethodName(JarEntry entry, String targetMethodName)
			throws SecurityException, ClassNotFoundException {
		String name = entry.getName();
		if (name.endsWith(CLASS_SUFFIX)) {
			/**
			 * Populate the class name
			 */
			name = name.replaceAll("/", ".")
					.substring(0, name.lastIndexOf("."));

			/**
			 * Retrieve the methods via reflection.
			 */
			Method[] methods = Class.forName(name).getDeclaredMethods();
			for (Method m : methods) {
				/**
				 * Print the message in console if the method name is expected.
				 */
				if (targetMethodName.equals(m.getName())) {
					System.out.println(String.format(
							"Method [%s] is included in Class [%s]",
							targetMethodName, name));
					break;
				}
			}

		}
	}
}