【问题标题】:Retrieving class inside a method using reflection使用反射检索方法内的类
【发布时间】:2015-06-22 06:10:34
【问题描述】:
class test {
    public static void main(String[] args) {
         new test();
    }
    void method() {
         class inside {
              int a;
              void methodinside() {}
         }
    }
}

我正在使用反射声明类,例如:

Class c = Class.forName("test");
Class[] cls = c.getDeclaredClasses();
for(Class cl : cls)
     System.out.println(cl.getName());

但是,我的程序找不到class inside

【问题讨论】:

  • 很有趣,因为我们可以用getEnclosingClass 做相反的事情。 ideone.com/nA3Zua
  • 如何在main中访问,而在另一个方法或另一个类中的类中访问???
  • 如果你想从main 访问该类,那么你必须在main 可以看到它的地方声明它。这些本地类的重点是在声明方法之外不可见。
  • 除了反思还有其他想法吗???
  • 这可能是 X-Y 问题。你真正想做什么?您正在开发某种 IDE 工具吗?

标签: java class oop reflection local-class


【解决方案1】:

getDeclaredClasses() 方法返回(来自javadoc)-

反映所有类和接口的 Class 对象数组 声明为此 Class 对象表示的类的成员。 这包括公共、受保护、默认(包)访问和私有 类声明的类和接口,但不包括继承的 类和接口。

所以它似乎没有返回您声明的任何内部类。这就是为什么您在 Class cls 的数组中一无所获。

【讨论】:

    【解决方案2】:

    我不认为有一种方法可以找到本地类(在方法中定义的类)。

    您可以 try to enumerate all classes in the package 然后使用 getEnclosureClass(与您要查找的相反)过滤它们。

    【讨论】:

    • 我也不相信有办法枚举一个包中的所有类。
    • 在类文件上试试看。有创建文件 test$1inside.class
    【解决方案3】:

    这是一种在方法中获取内部类的方法。

    public class Main {
        public static void main(String[] args) throws ClassNotFoundException {
            Class<?> clazz = Class.forName("Outer$1InnerMethodClass");
            System.out.println(clazz.getName());
    
            clazz = Class.forName("Outer$2InnerMethodClass");
            System.out.println(clazz.getName());
    
            clazz = Class.forName("Outer$2InnerMethodClass$1InnerMethodInnetMethod");
            System.out.println(clazz.getName());
        }
    
    }
    
    class Outer{
        void outerMethod1() {
            class InnerMethodClass {
                 int a;
                 void innerMethod() {}
            }
       }
    
        void outerMethod2() {
            class InnerMethodClass {
                 int a;
                 void innerMethod() {
                     class InnerMethodInnetMethod{
    
                     }
                 }
            }
       }
    }
    

    【讨论】:

    • 这不能安全地概括。规范没有规定本地类的确切名称,仅规定其格式。
    【解决方案4】:

    在 Java 中,没有设计用于枚举类的通用方法。这是因为类可以从任何地方加载,或者动态创建。将类文件存储在 JAR 或目录中只是任何可能的类加载器之一。

    因此,虽然假设封闭类是已知的、可枚举的集合可能更合理,但提供仅在这种特殊情况下有效的方法是没有意义的。

    如果您假设URLClassLoader 的常见情况,您可以将底层 URL 视为文件系统并枚举其内容。如果您正在创建一个工具来处理现有的第三方代码,这可能是合适的,并且它甚至已被许多 Java EE 标准采用(我觉得这是错误的)。

    如果您正在创建插件机制,providing metadata in a well-known location 更高效、更可靠,并且可以与任何有效的类加载器一起使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-17
      • 1970-01-01
      • 1970-01-01
      • 2010-12-11
      • 2011-07-25
      • 2014-01-07
      • 2019-03-03
      • 1970-01-01
      相关资源
      最近更新 更多