Java 我们可以使用反射获得本地类吗?

Java 我们可以使用反射获得本地类吗?,java,Java,有没有办法从Test.Class获取类X class Test { void test() { class X { } } } 使用反射?这与使用class.forName创建内部类的方式类似 class Test { class X {} // "Test$X" } 除了它前面有一个数字(很像一个匿名的内部类),因为可以有多个本地定义 class Test { void test() { class X {

有没有办法从Test.Class获取类X

class Test {

    void test() {
        class X {
        }
    }
}

使用反射?

这与使用
class.forName创建内部类的方式类似

class Test {
    class X {} // "Test$X"
}
除了它前面有一个数字(很像一个匿名的内部类),因为可以有多个本地定义

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"
    }
}

了解JLS是否保证基于代码顺序的编号是很有意思的,但我不会对它下任何赌注。

这类似于使用
class.forName执行内部类的方式。

class Test {
    class X {} // "Test$X"
}
除了它前面有一个数字(很像一个匿名的内部类),因为可以有多个本地定义

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"
    }
}

了解JLS是否保证基于代码顺序的编号是很有意思的,但我不会对它下任何赌注。

假设在
Main
类中有一个自包含的示例,您可以使用以下习惯用法:

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(){}
            }
        }
    }
}
输出

[void test.Main$Test$1Foo.bar()]

假设在
Main
类中有一个自包含的示例,您可以使用以下习惯用法:

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(){}
            }
        }
    }
}
输出

[void test.Main$Test$1Foo.bar()]

通过访问
ClassLoader
对象上的
classes
字段,可以使用反射识别这些匿名类。此字段显示跟踪所有加载的类。如果您随后检查返回null的类,那么您将能够识别这些类。它不是很漂亮,但在这种情况下它让我得到了class
X

唯一需要注意的是,如果类
X
未在任何地方引用,则这似乎不起作用

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();

  }
}
公共类主{
publicstaticvoidmain(String…args)抛出NoSuchFieldException、IllegalAccessException{
X类{
}
ClassLoader ClassLoader=RiskWrapper.class.getClassLoader();
System.setSecurityManager(新的SecurityManager(){
@凌驾
公共作废检查权限(权限perm){
}
});
字段类=ClassLoader.class.getDeclaredField(“类”);
class.setAccessible(true);

Vector通过访问
ClassLoader
对象上的
classes
字段,您可以使用反射来识别这些匿名类。该字段似乎跟踪所有加载的类。如果您随后检查返回null的类,您将能够识别这些类。它不是很漂亮,但它让我很困惑在这种情况下,类
X

唯一需要注意的是,如果类
X
未在任何地方引用,则这似乎不起作用

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();

  }
}
公共类主{
publicstaticvoidmain(String…args)抛出NoSuchFieldException、IllegalAccessException{
X类{
}
ClassLoader ClassLoader=RiskWrapper.class.getClassLoader();
System.setSecurityManager(新的SecurityManager(){
@凌驾
公共作废检查权限(权限perm){
}
});
字段类=ClassLoader.class.getDeclaredField(“类”);
class.setAccessible(true);

向量您需要了解Java编译器/JVM如何将本地类名映射到内部类名,然后只需使用正确的内部类名调用
class.forName(…)
。您需要了解Java编译器/JVM如何将本地类名映射到内部类名,然后只需调用
class.forName(…)
具有正确的内部类名。