Java reflecting on method scope variables

2019-05-27 15:42发布

问题:

Using reflection you can get pretty much everything relating to a class. You can get all the declared methods, fields and classes (and possibly even more), but i couldn't find a way to reflect on a method so i could find out what classes that method might be using.

Essentially i would like to find out all dependencies to other classes that a given class has.

Example: Given the following code:

import com.yada.yada.yada.SomeClass 

public class MyClass
{
  public MyClass
  {
    new SomeClass();
  }
}

How can i find out that MyClass is using SomeClass in its constructor?

I was trying to think of a way to get all import statements defined in a class file but i couldn't find anything that way either. But, assuming there's a way to somehow dig up all import statements defined in a class file, how would one find out about classes defined in the same package, which do not require an import statement?

EDIT:

Scenario: The goal is to send the bytecode of this class (MyClass) to another process. This other process then takes in the bytecode and loads the class (MyClass) using class loaders, and so on. The problem is that when i try to create and run an instance of MyClass in the other process it fails because it cannot find a definition for SomeClass.

If SomeClass were a member of MyClass it wouldn't be a problem but since the only reference to it lies in a method, there's no way to get to it via reflection?

回答1:

I think the closest you can come to getting all of a class's dependencies is by hooking into the class loader mechanism and recording what classes get loaded when the class you're examining is instantiated and its methods are called. Of yourse, you'd transitively also get all the classes that it indirectly depends on, but depending on what you want to do with the information, that may be what you actually need.

But it's impossible to do for all cases (just imagine a method that uses Class.forName() to ask for a random class name every time it's called).

how would one find out about classes defined in the same package

That's actually impossible to do in general, since the class loader concept really only allows asking for a fully qualified class name, and either getting that class or a ClassNotFoundException. Classes can be loaded from a webserver (in the case of applets) or generated on the fly, so you cannot know whether a specific class exists except by asking for it.



回答2:

You can't (unless you decompile the bytecode). A local variable is not tied to any class instance, and it does not even exist for most of the lifetime of the class or its instances, so you can't access it via reflection.

What are you trying to achieve? Maybe if you tell us about your actual problem, rather than a perceived solution, we are better able to help.



回答3:

Reflection does not help you here. The only way I can think of that you can achieve this is through a byte code tool like asm.

Create a ClassVisitor that gathers dependencies from

  • Class declarations
  • Annotations
  • Local variable declarations
  • Field declarations
  • Method declarations
  • Method invocations
  • (have I forgotten anything?)