String.valueOf
은 메소드에서 실제로 호출되지 않으므로보다 광범위한 용어를 사용합니다. 참조 된 메소드에 대해 이야기하십시오. 여기에는 호출 된 메소드가 포함됩니다. ASM (java-bytecode-asm)를 사용하여 그들 모두를 수집하는 한 가지 방법은 다음과 같습니다 당신의 방법은`create`는 방법`String.valueOf`를 호출하지,하지만 방법에 대한 참조를 가져옵니다에만 않기 때문에이 올바른지
import java.io.IOException;
import java.util.Optional;
import org.objectweb.asm.*;
public class FindAllReferencedMethods {
class Example {
void create() {
System.out.println("TEST");
Optional.of("String").map(String::valueOf).get();
}
}
public static void main(String[] args) throws IOException {
ClassReader r = new ClassReader(Example.class.getName());
r.accept(new ClassVisitor(Opcodes.ASM5) {
@Override
public MethodVisitor visitMethod(
int access, String name, String desc, String sig, String[] ex) {
return name.equals("create")? new MethodRefCollector(): null;
}
}, ClassReader.SKIP_DEBUG|ClassReader.SKIP_FRAMES);
}
static void referencedMethod(String owner, String name, String desc) {
System.out.println(
Type.getObjectType(owner).getClassName() + "." + name + " " + desc);
}
static class MethodRefCollector extends MethodVisitor {
public MethodRefCollector() {
super(Opcodes.ASM5);
}
@Override
public void visitMethodInsn(
int opcode, String owner, String name, String desc, boolean itf) {
referencedMethod(owner, name, desc);
}
@Override
public void visitInvokeDynamicInsn(
String name, String desc, Handle bsm, Object... bsmArgs) {
if(bsm.getOwner().equals("java/lang/invoke/LambdaMetafactory")
&& bsm.getDesc().equals(bsm.getName().equals("altMetafactory")?
ALT_SIG: MF_SIG)) {
Handle target = (Handle)bsmArgs[1];
referencedMethod(target.getOwner(), target.getName(), target.getDesc());
}
}
}
static String MF_SIG = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;"
+"Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/"
+"MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;";
static String ALT_SIG = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;"
+"Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;";
}
주 그것을 map 메소드에 전달합니다. 엄밀히 말하자면, 메소드는 전달 메소드가 실제로 호출되는지 여부를 알지 못합니다. – luk2302
알아낼 수있는 방법은 무엇입니까 :)? – Trind
그리고 전달 된 메소드에 대한 참조 만 필요합니다. – Trind