【问题标题】:How to get enclosed class? [duplicate]如何进入封闭课堂? [复制]
【发布时间】:2017-06-10 15:44:33
【问题描述】:

我知道Class.getDeclaredClasses() 可以获取它声明的所有类,但不包括匿名类。

我想知道有没有办法通过封闭类获取所有封闭类?例如,我想获取在Root 中定义的所有封闭类用于测试目的。

class Root{
   void run(){
      Runnable task = new Runnable(){
         public void run(){}
      };

      task.getClass().getEnclosingClass();// return Root.class
      // but I want to get all enclosed class via Root.class, for example:
     // Root.class... == task.getClass() 
   }
}

预期结果是:[class of task]

【问题讨论】:

  • task 是局部变量的名称,我认为没有任何方法可以得到它。或者你到底想达到什么目标?
  • @luk2302 但task 是在Root 中定义的,编译器会为匿名类生成一个额外的类。
  • getDeclaredClasses() 会这样做吗?我没用过。啊,不,显然这就是您要问的问题,但您忽略了es
  • @DavidConrad getDeclaredClasses() 返回所有声明的类,除了匿名类。
  • 您的需求是什么,您的用例是什么?这可能是伪装的XY Problem

标签: java java-8


【解决方案1】:

如果您知道匿名类的命名方案,可以尝试使用RootClassLoader 加载它:

javac 的命名方案是<enclosing_class_name>$<anonymous_class_number>:

Class<?> enclosing = Root.class;

try{
    Class<?> anon1 = enclosing.getClassLoader().loadClass(enclosing.getName() + "$1");
    System.out.println(anon1); // prints: class Root$1
} catch (ClassNotFoundException e) {
    System.out.println("no anonymous classes");
}

【讨论】:

  • 请注意,虽然指定了命名方案,但未指定实际数量。 docs.oracle.com/javase/specs/jls/se8/html/jls-13.html#jls-13.1 虽然不太可能,但它是合法的,例如数字是随机的或从 1 以外的某个数字开始。所以这是可行的,但不一定必须有效。
  • 谢谢您,先生。我立即尝试并尽快关闭问题。
  • 最好使用findLoadedClass 而不是loadClass
  • 使用类路径可能会更健壮。使用 Guava,您可以使用 ClassPath 并执行类似 ClassPath.from(Outer.class.getClassLoader()).getAllClasses().stream().filter(info -&gt; info.getName().matches(Outer.class.getName() + "\\$[0-9]+")).map(ClassPath.ClassInfo::load).collect(toList()) 的操作。
  • @Radiodef 关于可能发生的潜在重命名的绝佳观点。一个例子是脱糖的 lambda。目前是lambda$go$0,其中go 是声明特定lambda 的方法;虽然它曾经是lambda$0...
猜你喜欢
  • 1970-01-01
  • 2013-05-18
  • 2015-08-30
  • 1970-01-01
  • 1970-01-01
  • 2021-04-09
  • 1970-01-01
  • 2019-07-03
  • 1970-01-01
相关资源
最近更新 更多