Java 我们可以使用反射获得本地类吗?
有没有办法从Test.Class获取类XJava 我们可以使用反射获得本地类吗?,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 {
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的类,那么您将能够识别这些类。它不是很漂亮,但在这种情况下它让我得到了classX
唯一需要注意的是,如果类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(…)
具有正确的内部类名。