Is there a way to get Class X from Test.class
class Test {
void test() {
class X {
}
}
}
using reflection?
It's similar to how you'd do an inner class using Class.forName
class Test {
class X {} // "Test$X"
}
Except it's prefaced by a number (much like an anonymous inner class) since there can be multiple local definitions
class Test {
void test() {
class X { // "Test$1X"
}
}
void test2() {
class X { // "Test$2X"
}
class Y { // "Test$1Y"
}
System.out.println(new X(){}) // "Test$1"
System.out.println(new X(){}) // "Test$2"
System.out.println(new Y(){}) // "Test$3"
}
}
It would be interesting to know if the JLS guarantees the numbering based on the order of the code, but I wouldn't place any bets on it.
You can use the following idiom, assuming a self-contained example in a Main
class:
public class Main {
public static void main(String[] args) throws Exception {
Class c = Class.forName("test.Main$Test$1Foo");
// testing methods
System.out.println(Arrays.toString(c.getDeclaredMethods()));
}
static class Test {
void test() {
class Foo {
void bar(){}
}
}
}
}
Output
[void test.Main$Test$1Foo.bar()]
You can identify these anonymous classes using reflection, by accessing the classes
field on the ClassLoader
object. This field appears to keep track of all the loaded classes. If you then check for classes where getCanonicalName
return null, you will then be able to identify these classes. It is not very pretty, but it gets me class X
in this case.
The only caveat is that this doesn't appear to work if class X
is not referenced anywhere.
public class Main {
public static void main(String... args) throws NoSuchFieldException, IllegalAccessException {
class X {
}
ClassLoader classLoader = RiskWrapper.class.getClassLoader();
System.setSecurityManager(new SecurityManager() {
@Override
public void checkPermission(Permission perm) {
}
});
Field classes = ClassLoader.class.getDeclaredField("classes");
classes.setAccessible(true);
Vector<Class<?>> loadedClasses = (Vector<Class<?>>)classes.get(classLoader);
Class<X> xClass = X.class;
for(Class<?> loadedClass : loadedClasses) {
if(loadedClass.equals(xClass)) {
System.out.println("Found anonymous class " + loadedClass.getName());
}
}
System.out.println();
}
}
Output:
Found anonymous class Main$1X
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.