возвращаемый метод Java - PullRequest
       7

возвращаемый метод Java

1 голос
/ 05 января 2012

У меня есть такие методы:

public File method1(){
    method2()
}

public method2(){
do something..
and get method1 return type(in this case File)
}

Как мне это получить? я попробовал вот так ..

Throwable t = new Throwable();
StackTraceElement[] elements = t.getStackTrace();

и получите все методы для элементов. И после этого getReturnType, но это не работает. Я тоже пробовал

public File method1(){
    method2(this.getClass());
}

public method2(Class<?> className){
   //problem here
}

Но здесь проблема в том, что я не могу сравнить два элемента: один в стеке и один из classname.getMethods().

Есть ли способ, которым я могу отправить метод возврата типа в method2? Мне нужно это из-за создания какого-то журнала, похожего на историю. Я знаю, что это можно сделать с помощью aspectJ, но я должен сделать это как-то так.

EDIT:

Основная проблема, с которой я столкнулся, заключается в том, что я могу получить вывод стека и посмотреть метод, который вызвал мой метод2 - это один фрагмент, который мне нужен! Также мне нужен тип возвращаемого значения этого метода, но стек не содержит эту информацию. Теперь я могу получить все методы из класса, где находится «метод, вызвавший method2». Список этих методов, содержат все, возвращаемый тип, входные параметры ... но это довольно большой список, 63 метода. Поэтому я должен как-то сравнить их, чтобы выяснить, какой из них из STACK. Я не могу сопоставить их, используя имя, потому что некоторые отличаются в зависимости от типа возвращаемого значения, другой хэш-код - вот где я застрял.

Ответы [ 4 ]

2 голосов
/ 05 января 2012

Почему с отражением так сложно?

public File method1() {
    method2()
}

public void method2() {
    Class<?> returnType = this.getClass().getMethod("method1").getReturnType();
}

Конечно, вам придется обрабатывать исключения.

2 голосов
/ 05 января 2012

Обновление

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

Я рекомендуюВы пересматриваете свой дизайн.Если method2 необходимо знать тип возврата метода, который его вызывает, то соответствующий метод должен передать эту информацию в method2.Попытка собрать эту информацию из стека времени выполнения не только неэффективна, но и является красным флагом разработки.

Пример:

public File method1(File f) {
    // ...

    method2(File.class);
}

public String method1(String s) {
    // ...

    method2(String.class);
}

public Foo method1(Foo f) {
    // ...

    method2(Foo.class);
}

Там у нас есть три перегрузки по method1.Это не проблема для method2, потому что каждый из них сообщает method2, каков его тип возврата - или, точнее, я надеюсь, что ему нужно method2, чтобы создать для него или что-то еще.

Оригинальный ответ

Для конкретного случая, который вы перечислите (особенно в конце вашего вопроса), вы можете сделать это:

public File method1(){
    method2(File.class);
}

File.class является экземпляром Class для класса File.

Для общего случая определения типа возвращаемого значения метода в классе можно использовать отражение API .Получите экземпляр Class для класса, содержащего метод, с помощью Class.forName, найдите метод на этом экземпляре Class, используя Class#getMethod, затем используйте Method#getReturnType на этом Method, чтобы узнать класс возвращаемого типа.

0 голосов
/ 05 января 2012

Обновленный ответ

Использование комбинации StackTrace и Reflection

import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Vector;

public class CallingMethodReturnType
{
    public static void main( String[] args )
    {
        CallingMethodReturnType app = new CallingMethodReturnType();
        app.method1();
        app.method3();
    }

    public File method1(){
        method2();
        return null;
    }

    public ArrayList method3(){
        method4();
        return null;
    }

    public Vector method4() {
        method2();
        return null;
    }

    public void method2(){
        Method method;
        try {
            StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
            StackTraceElement ste = stackTraceElements[2];
            String callerMethodName = ste.getMethodName();
            method = this.getClass().getMethod(callerMethodName, null);
            Class returnType = method.getReturnType();
            System.out.println(returnType);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

    }
}

Также проверьте вопрос Как найти вызывающего метода с использованием stacktrace илиотражение? если вы обеспокоены производительностью.

Оригинальный ответ

Вы можете использовать API отражения следующим образом

    public method2(){
     //do something and get method1 return type(in this case File)
     Method method = this.getClass().getMethod("method1", null);
     Class returnType = method.getReturnType();
    }
0 голосов
/ 05 января 2012

Если класс, который вы возвращаете, имеет пустой конструктор, вы можете создать экземпляр возвращаемого типа локально в method2 () и использовать его, но это опасно и не является универсальным.

Вы можете сделать x.getClass (). GetName () и выполнить операцию переключения.

Однако я хотел бы предложить вам реструктурировать это с использованием AspectJ и поместить точку обрезки в родительский вызов, чтобы собрать информацию, которая вам действительно нужна, до того, как вы опуститесь в стек. Я догадываюсь немного о вашем намерении, но всякий раз, когда вы анализируете вывод стека для получения информации о типе, я думаю, что дизайн заслуживает второго взгляда.

...