ASM 中,ClassReader 類:對已存在的進行解析,並提供獲取類信息的方法。java
經過 ClassReader ,實現對一個類的解析。web
依據以下流程,判斷出一個類是否實現了某個接口:ide
具體實現代碼以下 :測試
package utils; import org.objectweb.asm.ClassReader; import java.io.IOException; import java.util.Set; /** * 判斷某類是否實現了指定接口集合 * * @author pengpj * @date 2018/11/27 */ public class SpecifiedInterfaceImplementionChecked { /** * 判斷是否實現了指定接口 * * @param reader class reader * @param interfaceSet interface collection * @return check result */ public static boolean hasImplSpecifiedInterfaces(ClassReader reader, Set<String> interfaceSet) { if (isObject(reader.getClassName())) { return false; } try { if (containedTargetInterface(reader.getInterfaces(), interfaceSet)) { return true; } else { ClassReader parent = new ClassReader(reader.getSuperName()); return hasImplSpecifiedInterfaces(parent, interfaceSet); } } catch (IOException e) { return false; } } /** * 檢查當前類是 Object 類型 * * @param className class name * @return checked result */ private static boolean isObject(String className) { return "java/lang/Object".equals(className); } /** * 檢查接口及其父接口是否實現了目標接口 * * @param interfaceList 待檢查接口 * @param interfaceSet 目標接口 * @return checked result * @throws IOException exp */ private static boolean containedTargetInterface(String[] interfaceList, Set<String> interfaceSet) throws IOException { for (String inter : interfaceList) { if (interfaceSet.contains(inter)) { return true; } else { ClassReader reader = new ClassReader(inter); if (containedTargetInterface(reader.getInterfaces(), interfaceSet)) { return true; } } } return false; } }
部分測試用例以下:code
private static Set<String> set; static { if (set == null) { set = new HashSet<>(); } set.add("com/cvte/myou/apm/agent/utils/SpecifiedInterfaceImplCheckedTest$A"); } @Test public void hasImplSpecifiedInterfacesTest() throws IOException { Assert.assertEquals(true, SpecifiedInterfaceImplChecked.hasImplSpecifiedInterfaces(new ClassReader(B.class.getName()), set)); Assert.assertEquals(true, SpecifiedInterfaceImplChecked.hasImplSpecifiedInterfaces(new ClassReader(C.class.getName()), set)); } @Test public void hasImplSpecifiedInterfacesObjectTest() throws IOException { Assert.assertEquals(false, SpecifiedInterfaceImplChecked.hasImplSpecifiedInterfaces(new ClassReader(Object.class.getName()), set)); } @Test public void hasImplSpecifiedInterfacesInterfaceTest() throws IOException { Assert.assertEquals(true, SpecifiedInterfaceImplChecked.hasImplSpecifiedInterfaces(new ClassReader(D.class.getName()), set)); } interface A { void hello(); } class B implements A { @Override public void hello() { } } abstract class C implements A { } interface D extends A { }
ASM 中提供了 ClassReader ,對已存在的類進行解析,可讓咱們在沒有源碼的狀況下,對類進行操做。blog