java 反射jar_Java:从JAR文件中的类文件中获取方法存根的简便方法?反射?

小编典典

根据aioobe的回答,您还可以使用ASM的树API(而不是其访问者API)来解析JAR文件中包含的类文件的内容。同样,您可以使用JarFile类读取JAR文件中包含的文件。这是如何完成此操作的示例:

该printMethodStubs方法接受a JarFile并继续打印出所有类文件中包含的所有方法的描述。

public void printMethodStubs(JarFile jarFile) throws Exception {

Enumeration entries = jarFile.entries();

while (entries.hasMoreElements()) {

JarEntry entry = entries.nextElement();

String entryName = entry.getName();

if (entryName.endsWith(".class")) {

ClassNode classNode = new ClassNode();

InputStream classFileInputStream = jarFile.getInputStream(entry);

try {

ClassReader classReader = new ClassReader(classFileInputStream);

classReader.accept(classNode, 0);

} finally {

classFileInputStream.close();

}

System.out.println(describeClass(classNode));

}

}

}

该describeClass方法接受一个ClassNode对象并继续对其进行描述及其相关方法:

public String describeClass(ClassNode classNode) {

StringBuilder classDescription = new StringBuilder();

Type classType = Type.getObjectType(classNode.name);

// The class signature (e.g. - "public class Foo")

if ((classNode.access & Opcodes.ACC_PUBLIC) != 0) {

classDescription.append("public ");

}

if ((classNode.access & Opcodes.ACC_PRIVATE) != 0) {

classDescription.append("private ");

}

if ((classNode.access & Opcodes.ACC_PROTECTED) != 0) {

classDescription.append("protected ");

}

if ((classNode.access & Opcodes.ACC_ABSTRACT) != 0) {

classDescription.append("abstract ");

}

if ((classNode.access & Opcodes.ACC_INTERFACE) != 0) {

classDescription.append("interface ");

} else {

classDescription.append("class ");

}

classDescription.append(classType.getClassName()).append("\n");

classDescription.append("{\n");

// The method signatures (e.g. - "public static void main(String[]) throws Exception")

@SuppressWarnings("unchecked")

List methodNodes = classNode.methods;

for (MethodNode methodNode : methodNodes) {

String methodDescription = describeMethod(methodNode);

classDescription.append("\t").append(methodDescription).append("\n");

}

classDescription.append("}\n");

return classDescription.toString();

}

该describeMethod方法接受a

MethodNode并返回一个描述方法签名的字符串:

public String describeMethod(MethodNode methodNode) {

StringBuilder methodDescription = new StringBuilder();

Type returnType = Type.getReturnType(methodNode.desc);

Type[] argumentTypes = Type.getArgumentTypes(methodNode.desc);

@SuppressWarnings("unchecked")

List thrownInternalClassNames = methodNode.exceptions;

if ((methodNode.access & Opcodes.ACC_PUBLIC) != 0) {

methodDescription.append("public ");

}

if ((methodNode.access & Opcodes.ACC_PRIVATE) != 0) {

methodDescription.append("private ");

}

if ((methodNode.access & Opcodes.ACC_PROTECTED) != 0) {

methodDescription.append("protected ");

}

if ((methodNode.access & Opcodes.ACC_STATIC) != 0) {

methodDescription.append("static ");

}

if ((methodNode.access & Opcodes.ACC_ABSTRACT) != 0) {

methodDescription.append("abstract ");

}

if ((methodNode.access & Opcodes.ACC_SYNCHRONIZED) != 0) {

methodDescription.append("synchronized ");

}

methodDescription.append(returnType.getClassName());

methodDescription.append(" ");

methodDescription.append(methodNode.name);

methodDescription.append("(");

for (int i = 0; i < argumentTypes.length; i++) {

Type argumentType = argumentTypes[i];

if (i > 0) {

methodDescription.append(", ");

}

methodDescription.append(argumentType.getClassName());

}

methodDescription.append(")");

if (!thrownInternalClassNames.isEmpty()) {

methodDescription.append(" throws ");

int i = 0;

for (String thrownInternalClassName : thrownInternalClassNames) {

if (i > 0) {

methodDescription.append(", ");

}

methodDescription.append(Type.getObjectType(thrownInternalClassName).getClassName());

i++;

}

}

return methodDescription.toString();

}

2020-12-03

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值