Как я могу найти все методы, которые вызывают данный метод в Java?
Мне нужно получить список всех методов вызова для интересующего меня метода в Java. Есть ли инструмент, который может мне помочь? Изменить: я забыл упомянуть, что мне нужно сделать это из программы. Я использую Java Pathfinder, и я хочу запустить его всеми методами, которые называют мой метод интереса.
Ребята miklosar действительно отредактировали q и говорят, что это должно произойти во время выполнения, кажется, что бесчисленное множество людей говорят, как это сделать в IDE. До голосования @chadwick
возможно, вы могли бы объяснить, почему вы должны делать это во время выполнения, поскольку люди, возможно, не сталкивались с этим требованием.
11 ответов
Для анализа байт-кода я бы рекомендовал ASM. Учитывая список классов для анализа, может быть сделан посетитель, который находит интересующие вас вызовы методов. Ниже приведена одна реализация, которая анализирует классы в файле jar.
Обратите внимание, что ASM использует internalNames с ‘/’ вместо ‘.’ как разделитель. Укажите целевой метод как стандартное объявление без модификаторов.
Например, чтобы перечислить методы, которые могут быть вызваны System.out.println( «foo» ) в java runtime jar:
java -cp "classes;asm-3.1.jar;asm-commons-3.1.jar" App \ c:/java/jdk/jre/lib/rt.jar \ java/io/PrintStream "void println(String)"
Изменить: добавлены исходные номера и номера строк: обратите внимание, что это указывает только на вызов последнего целевого метода для каждого метода вызова — оригинал q хотел узнать только, какие методы. Я оставляю это как упражнение для читателя, чтобы показать номера строк объявления вызывающего метода или номера строк каждого целевого вызова, в зависимости от того, что вы на самом деле после.:)
LogSupport.java:44 com/sun/activation/registries/LogSupport log (Ljava/lang/String;)V LogSupport.java:50 com/sun/activation/registries/LogSupport log (Ljava/lang/String;Ljava/lang/Throwable;)V . Throwable.java:498 java/lang/Throwable printStackTraceAsCause (Ljava/io/PrintStream;[Ljava/lang/StackTraceElement;)V -- 885 methods invoke java/io/PrintStream println (Ljava/lang/String;)V
public class App < private String targetClass; private Method targetMethod; private AppClassVisitor cv; private ArrayListcallees = new ArrayList(); private static class Callee < String className; String methodName; String methodDesc; String source; int line; public Callee(String cName, String mName, String mDesc, String src, int ln) < className = cName; methodName = mName; methodDesc = mDesc; source = src; line = ln; >> private class AppMethodVisitor extends MethodAdapter < boolean callsTarget; int line; public AppMethodVisitor() < super(new EmptyVisitor()); >public void visitMethodInsn(int opcode, String owner, String name, String desc) < if (owner.equals(targetClass) && name.equals(targetMethod.getName()) && desc.equals(targetMethod.getDescriptor())) < callsTarget = true; >> public void visitCode() < callsTarget = false; >public void visitLineNumber(int line, Label start) < this.line = line; >public void visitEnd() < if (callsTarget) callees.add(new Callee(cv.className, cv.methodName, cv.methodDesc, cv.source, line)); >> private class AppClassVisitor extends ClassAdapter < private AppMethodVisitor mv = new AppMethodVisitor(); public String source; public String className; public String methodName; public String methodDesc; public AppClassVisitor() < super(new EmptyVisitor()); >public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) < className = name; >public void visitSource(String source, String debug) < this.source = source; >public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) < methodName = name; methodDesc = desc; return mv; >> public void findCallingMethodsInJar(String jarPath, String targetClass, String targetMethodDeclaration) throws Exception < this.targetClass = targetClass; this.targetMethod = Method.getMethod(targetMethodDeclaration); this.cv = new AppClassVisitor(); JarFile jarFile = new JarFile(jarPath); Enumerationentries = jarFile.entries(); while (entries.hasMoreElements()) < JarEntry entry = entries.nextElement(); if (entry.getName().endsWith(".class")) < InputStream stream = new BufferedInputStream(jarFile.getInputStream(entry), 1024); ClassReader reader = new ClassReader(stream); reader.accept(cv, 0); stream.close(); >> > public static void main( String[] args ) < try < App app = new App(); app.findCallingMethodsInJar(args[0], args[1], args[2]); for (Callee c : app.callees) < System.out.println(c.source+":"+c.line+" "+c.className+" "+c.methodName+" "+c.methodDesc); >System.out.println("--\n"+app.callees.size()+" methods invoke "+ app.targetClass+" "+ app.targetMethod.getName()+" "+app.targetMethod.getDescriptor()); > catch(Exception x) < x.printStackTrace(); >> >
Получение списка всех доступных методов из библиотеки jar
Подскажите пожалуйста, как получить из jar библиотеки список всех методов, которые могут быть использованы в своих приложениях. Т.е. как я понимаю это все public методы из public классов. Желательно получить прототипы методов. И ещё хотел бы уточнить, оказывает ли package влияние на доступность в public классе public метода.
MacBook: Горячие клавиши для выпада списка доступных методов и функций
Добрый день! Подскажите комбинацию клавиш на маковской клаве, с помощью которой выпадает в.
Получение списка доступных COM портов
Хочу получить список портов. Нашел пару примеров под делфи. Но в них используются несуществующие.
Получение списка доступных шрифтов
Как получить список установленных в системе шрифтов?
Получение всех доступных DHCP-серверов
Добрый день. Задача состоит в том, что бы через Командную строку вывести все доступные DHCP.
Имхо, нинужна. Это ООП-шный язык, и рассматривать методы отдельно от их классов — занятие потенциально бесперспективное.
Сообщение от xreal
Публичный метод публичного класса доступен везде.
Вообще для задач такого вида Reflection API.
Вот, так а как имея на руках jar библиотеку получить из неё список типа такого:
1. класс — метод(аргументы)
2. класс — метод(аргументы)
.
Соответственно все паблик классы и их паблик методы. В принципе можно без аргументов даже.
Просто у нас же есть .class файлы в jar’e, которые содержат всю инфу необходимую. Ну для аналогии, это как получить список экспортируемых функций из DLL
Методы в классах — НЕ аналог функций в DLL. Класс Вы еще создать должны. Для чего надо знать сигнатуру конструктора, передать правильные параметры. Просто кинуть jar и использовать его — непросто, это надо ряд телодвижений предпринять.
Я понимаю, что это не совсем аналог функций из DLL.
Грубо говоря у меня есть jar библиотека, которая содержит интересные мне методы. Мне нужно знать какие методы из неё я смогу использовать.
Что значит классы, а не методы? Если класс не статический я создаю экземпляр класса, которому доступны публичные методы класса и использую их. Если же класс статический, то напрямую вызываю методы по имени класса. Или я что-то не так понимаю?
Вопрос собственно в том, чтобы получить полный список всех публичных классов их методов из jar файла.
xreal, для библиотек обычно есть доки. Или можно открыть архиватором, посмотреть, какой корневой пакет(обычно это org, com), пишете «import rootpack.» и появится список всего, что доступно. Тем более и так в IDE можно посмотреть, в дереве объектов. (NB, например)
Были б доки — не было б вопросов)) А вот «import rootpack» попробую, спасибо. В IDE — просто посмотреть, а мне надо список экспортируемый.
Добавлено через 29 минут
А куда писать import rootpack?
Сообщение от xreal
Что значит классы, а не методы? Если класс не статический я создаю экземпляр класса, которому доступны публичные методы класса и использую их. Если же класс статический, то напрямую вызываю методы по имени класса. Или я что-то не так понимаю?
1. Статическими могут быть только внутренние классы. Класс, не являющийсы внутренним, не может быть статическим.
2. Для создания экземпляра класса Вам надо знать, что этот класс делает и какие у него есть конструкторы. Никакой список методов Вам не поможет. Так что Вы должны сначала понять, зачем нужен этот класс, а потом уже — как использовать его нестатические методы.
Сообщение от xreal
Под rootpack имелся в виду корневой пакет. Т.е. если в библиотеке пакеты начинаются на org, то написать import org. (с точкой на конце) там, где прописываются все импорты — и можно получить следующий уровень пакета. Выбрать его, поставить точку — получить следующий урвоень, и так до классов.
Что-то мне кажется, что по Вашему уровню понимания происходящего Вам рано разбираться с неизвестными библиотеками при отсутствии документации.
Сообщение от tankomaz
Нет, он генерирует документацию по исходникам. Анализировать байткод он не умеет.
Проблему ТС решит самописная утилита, которая прочитает jar как zip, вытащит из него все имена класов, а потом пройдется по этим именам, загрузит каждый класс по имени и через reflection вытащит весь список методов, конструкторов и т.д. Но такая утилита, кмк, сильно превышает возможности ТС.
Хорошо, что если задача такая:
Я знаю описание класса, его конструкторов и тд. Я знаю часть публичных методов. И могу всем этим пользоваться, но мне нужно узнать те, что не описаны в документации, и пользоваться ими. Хотя они есть в этих же классах.
В итоге необходимо получить просто список всех методов которые могут быть использованы. Это и есть вся задача.
Добавлено через 6 минут
Я совсем не java программист. У меня другие задачи. Уровень понимания — когда-то давно я немного экспериментировал с java не более.
И, уважаемый эксперт Skipy, я создал тему, чтобы узнать есть ли простой способ это сделать. А вы мне рассказываете теорию работы с классами, вместо чёткого ответа на вопрос.
Если это решается только при помощи самописной утилиты — поверьте, это не сильно превышает мои возможности, но опыта java программирования, конечно, у меня не достаточно для быстрого написания такой утилиты, а разобраться и написать её не так уж и сложно. По сути просто — парсер.
Сообщение от xreal
Я знаю описание класса, его конструкторов и тд. Я знаю часть публичных методов. И могу всем этим пользоваться, но мне нужно узнать те, что не описаны в документации, и пользоваться ими. Хотя они есть в этих же классах.
В IDE после переменной типа класса ставите точку — и получаете список всех методов.
И, уважаемый эксперт Skipy, я создал тему, чтобы узнать есть ли простой способ это сделать. А вы мне рассказываете теорию работы с классами, вместо чёткого ответа на вопрос.
Когда вопрос нечеткий — ответа четкого быть не может. У Вас изначально неправильная аналогия приведена — Вы хотите получить методы из jar как функции из dll. А это невозможно. Идеологически.
Если это решается только при помощи самописной утилиты — поверьте, это не сильно превышает мои возможности, но опыта java программирования, конечно, у меня не достаточно для быстрого написания такой утилиты, а разобраться и написать её не так уж и сложно. По сути просто — парсер.
Парсер, говорите. Ну-ну. Интересно будет посмотреть, как Вы разберете jar на классы. Что-то мне подсказывает, что будут сюрпризы.
How to find where a method is used in Java project
I am working on learning a project which was already created by someone else. It was not followed a proper coding method (no comments and so on). Im finding it difficult to find where a method is used. I tried «find» but as it searches only a particular class im unable to get the answer. Im working in eclipse. So can anyone please help me out.
2 Answers 2
You can select method that you want to find and use «Ctrl +H» and references search.
Right click on the method in the editor, and from the pop-up menu select
depending on whether you want to search only in the current project, or in the entire workspace.
For the find references in workspace option, the default keyboard shortcut is: Shift + Ctrl + G
After invoking the command, the Search window will display an overview of all locations where the method is used.
actually both the answers work. So im confused which one to accept. Its unfair to select one and leave the other. So i thought of leaving both alone. Hope this is fair
I would encourage you to accept one. Not only because it will give you a little bit of reputation points, but also because the question can then be used to flag other questions as duplicates. So, I guess it’s up to you to figure out which answer you found the most useful. I personally don’t mind if you give the accept vote to the other poster.