简体   繁体   中英

java method return type

I have methods like this:

public File method1(){
    method2()
}

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

How do I get it? i tried like this..

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

and get all the methods for the elements. And after that, getReturnType , but it doesn't work. I also tried

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

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

But here the problem is that i can't compare two elements, the one on the stack and the one from classname.getMethods() .

Is there any way that I can send method return type to a method2 ? I need this because of making some history-like log. I know it can be done with aspectJ but I have to do it somehow like this.

EDIT:

The main problem I have is that I can get stack output, and see the method who called my method2 - that's one fragment I need! Also I need that method's return type, but the stack doesnt hold that information. Now, I can get all the methods from the class where the "method who called method2" is. The list of those methods, hold everything, return type, input parameters.. but that's a pretty big list, 63 methods. So I have to compare them somehow to find out which one is the one FROM STACK. I can't comapre them using name, because some differ with return type, hashcode is different - that's where I'm stuck.

Update

If you really need to do this from a stack trace (which I would strongly recommend avoiding), I don't think you can. The stack trace can tell you the class and method names, but it doesn't include the method's argument types, and so if the method is overloaded you can't tell which one called method2 .

I recommend you revisit your design. If method2 needs to know the return type of the method that calls it, then the method in question should pass that information into method2 . Attempting to gather that information from a runtime stack is not only inefficient, but it's a design red flag.

Example:

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

    method2(File.class);
}

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

    method2(String.class);
}

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

    method2(Foo.class);
}

There we have three overloads of method1 . This is not a problem for method2 , because each of them tells method2 what its return type is — or more accurately, I hope, what it needs method2 to create for it or whatever.

Original answer

For the specific case you list (esp. toward the end of your question), you can do this:

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

File.class is the Class instance for the File class.

For the general case of finding the type of the return value of a method in a class, you can use the reflection API . Get the Class instance for the class containing the method via Class.forName , look up the method on that Class instance using Class#getMethod , then use Method#getReturnType on that Method to find out the return type's class.

Why is it so difficult with reflection?

public File method1() {
    method2()
}

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

Of course, you'll have to handle the exceptions though.

If the class you are returning has an empty constructor, you could build a instance of the return type locally in method2() and use that, but that is dangerous and not generic.

You could do x.getClass().getName() and perform a switch operation.

What I would suggest, though, is that you consider rearchitecting this to use AspectJ and put a cut point in your parent call to collect the information you really want before you get too low in the stack. I'm guessing a little bit as to your intent, but any time you are parsing the stack output for type information I think the design deserves a second look.

Updated answer

Using combination of StackTrace and 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();
        }

    }
}

Also check question How do I find the caller of a method using stacktrace or reflection? if you are concerned with performance.

Original answer

You can use reflection API like this

    public method2(){
     //do something and get method1 return type(in this case File)
     Method method = this.getClass().getMethod("method1", null);
     Class returnType = method.getReturnType();
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM