如何使用kotlin中的反射查找包中的所有类

如何使用kotlin中的反射查找包中的所有类,kotlin,Kotlin,是否可以在给定的包中找到所有kotlin类 我也只需要带注释的类,但这没什么大不了的。有什么建议吗?由于类加载器的实现,JVM上的Kotlin在这方面遇到了与Java相同的问题 类加载器不需要告诉VM它可以提供哪些类,相反,它们只是传递给类的请求,并且必须返回一个类或抛出一个异常 来源和更多信息: 为了总结链接线程,有许多解决方案允许您检查当前的类路径 该库非常简单,并具有许多附加功能,如获取类的所有子类型,获取所有类型/成员,并使用一些注释进行注释,还可以选择使用匹配的注释参数进行注释,等等

是否可以在给定的包中找到所有
kotlin


我也只需要带注释的类,但这没什么大不了的。有什么建议吗?

由于类加载器的实现,JVM上的Kotlin在这方面遇到了与Java相同的问题

类加载器不需要告诉VM它可以提供哪些类,相反,它们只是传递给类的请求,并且必须返回一个类或抛出一个异常

来源和更多信息:

为了总结链接线程,有许多解决方案允许您检查当前的类路径

  • 该库非常简单,并具有许多附加功能,如获取类的所有子类型,获取所有类型/成员,并使用一些注释进行注释,还可以选择使用匹配的注释参数进行注释,等等
  • has,它返回POJO的-对于您的用例来说还不够,但是知道它很有用,因为番石榴几乎无处不在
  • 通过查询类加载器资源和代码源编写自己的类加载器。除非绝对无法添加库依赖项,否则不会建议此路线

    • 下面是一个查询类加载器资源的示例,改编自

      需要Java 8或更高版本

      // Call this function using something like:
      //     findClasses("com.mypackage.mysubpackage")
      // Modified from https://www.javaworld.com/article/2077477/java-tip-113--identify-subclasses-at-runtime.html
      fun findClasses(pckgname: String) {
          // Translate the package name into an absolute path
          var name = pckgname
          if (!name.startsWith("/")) {
              name = "/$name"
          }
          name = name.replace('.', '/')
      
          // Get a File object for the package
          val url: URL = Launcher::class.java.getResource(name)
          val directory = File(url.getFile())
      
          println("Finding classes:")
          if (directory.exists()) {
              // Get the list of the files contained in the package
              directory.walk()
                  .filter { f -> f.isFile() && f.name.contains('$') == false && f.name.endsWith(".class") }
                  .forEach {
                      val fullyQualifiedClassName = pckgname +
                          it.canonicalPath.removePrefix(directory.canonicalPath)
                          .dropLast(6) // remove .class
                          .replace('/', '.')
                      try {
                          // Try to create an instance of the object
                          val o = Class.forName(fullyQualifiedClassName).getDeclaredConstructor().newInstance()
                          if (o is MyInterfaceOrClass) {
                              println(fullyQualifiedClassName)
                              // Optionally, make a function call here: o.myFunction()
                          }
                      } catch (cnfex: ClassNotFoundException) {
                          System.err.println(cnfex)
                      } catch (iex: InstantiationException) {
                          // We try to instantiate an interface
                          // or an object that does not have a
                          // default constructor
                      } catch (iaex: IllegalAccessException) {
                          // The class is not public
                      }
                  }
          }
      }