2012-03-26 4 views
5

Краткая версия: Мне нужно найти способ в Java, чтобы найти предыдущий Method в стеке вызовов (обратите внимание на капитал «M» в методе - мне нужен фактический объект java.lang.reflect.Method).Найти метод вызова в Java

Справочная информация: Я работаю над расширением концепции Google Guava Preconditions.checkNotNull(...), которая позволит программисту одновременно проверять ВСЕ параметры для нуля и строить NPE на основе имен параметров вызывающего метода. Например:

public class MyClass 
{ 
    public void myMethod(Object arg1, Integer arg2, String arg3) 
    { 
     MyPreconditions.checkAllNotNull(arg1, arg2, arg3); 
    } 
} 

Таким образом, если первый аргумент был нулевым, тем NPE может прочитать arg1 cannot be null (MyClass:myMethod(Object, Integer, String)

Я уже работал, как получить вызывающий Class и я могу получить имена параметров с помощью Spring LocalVariableTableParameterNameDiscoverer (или через библиотеку Paranamer) у меня есть Method. Единственная часть, которую я не могу понять, - это как получить Method.

Я знаю, что вы можете использовать трассировку стека, чтобы получить метод имя, но это не помогает, если метод переопределен. Есть ли способ (даже с внутренними классами com.sun) получить фактический стек? В качестве альтернативы, я могу получить номер строки для вызывающего метода, так есть ли способ найти номер строки Method как извлеченный из объекта Class?

+0

Дубликат http://stackoverflow.com/questions/421280/in-java-how-do-i-find-the-caller-of-a-method-using-stacktrace-or-reflection –

ответ

1

«Я знаю, что вы можете использовать трассировку стека, чтобы получить имя метода, но это не помогает, если метод переопределен». Трассировка стека также содержит имя класса (и исходный файл), однако, в правильном порядке, даже если метод был переопределен.

Я не думаю, что существует (хороший, последовательный) способ получить фактический объект Method. В частности, это не тот, который работает с активным менеджером безопасности. Сам код безопасности Java использует некоторые трюки для этого, но репликация, которая не будет переносимой между различными виртуальными машинами.

3

Thread.getStackTrace() дает текущую стеклу. Оттуда вы можете получить имя класса и имя метода (даже если метод переопределен, вы увидите там точный класс) и получите метод путем отражения.

Но imo - это странно и не нужно. И об этом - вы предоставляете сообщение, которое в основном уже присутствует в стеке, которое будет сгенерировано, если вызов Preconditions завершится с ошибкой.

+0

Вы можете ' t последовательно разрешает объект 'Method', если класс приходит от другого загрузчика классов. – Dolda2000

+0

Ну, вы можете получить трассировку непосредственно из «Throwable», например: 'try {throw new Exception (« преднамеренный »);} catch (Exception e) {e.getStackTrace(); } '. Но согласился, что это немного странно, чтобы это нужно ... – user268396

+0

@ Dolda2000, которым является метод 'getClassLoader()' для объектов класса. Либо вы получаете действительный экземпляр класса ClassLoader, либо получаете «null», что означает загрузчик. Тогда вы берете его оттуда ...? – user268396