我想做这样的事情:
List<Animal> animals = new ArrayList<Animal>();
for( Class c: list_of_all_classes_available_to_my_app() )
if (c is Animal)
animals.add( new c() );
Run Code Online (Sandbox Code Playgroud)
所以,我想查看我的应用程序的Universe中的所有类,当我找到一个来自Animal的类时,我想创建一个该类型的新对象并将其添加到列表中.这允许我添加功能而无需更新事物列表.我可以避免以下情况:
List<Animal> animals = new ArrayList<Animal>();
animals.add( new Dog() );
animals.add( new Cat() );
animals.add( new Donkey() );
...
Run Code Online (Sandbox Code Playgroud)
通过上面的方法,我可以简单地创建一个扩展Animal的新类,它将自动被拾取.
更新:2008年10月16日上午9:00太平洋标准时间:
这个问题引起了很多很好的回应 - 谢谢.从回答和我的研究中,我发现我真正想要做的就是在Java下不可能.有一些方法,比如ddimitrov的ServiceLoader机制可以工作 - 但它们对我想要的东西非常重,我相信我只是将问题从Java代码转移到外部配置文件.
另一种表达我想要的方式:我的Animal类中的静态函数查找并实例化从Animal继承的所有类 - 无需任何进一步的配置/编码.如果我必须配置,我也可以在Animal类中实例化它们.我理解,因为Java程序只是一个松散的.class文件联合体,就像它一样.
有趣的是,在C#中,这似乎相当微不足道.
我需要读取Java包中包含的类.这些类在classpath中.我需要直接从Java程序执行此任务.你知道一个简单的方法吗?
List<Class> classes = readClassesFrom("my.package")
Run Code Online (Sandbox Code Playgroud) 我正在开发一个应用程序(Quartz调度程序),我们有一个工作类负责实际执行工作,我们需要在Quartz调度程序中创建触发器时告诉/传递作业类的名称.
我想为所有想要使用API的人提供一个扩展点(除了我将作为API的一部分提供的一些通用作业).我们的想法是创建一个(标记)接口,如果有人想要将它们的类声明为调度程序作业类,那么他们所要做的就是(声明)实现接口.
我不确定如何找到遵循合同的类(通过实现接口),以便我可以向想要在调度程序中安排触发器的用户显示它们.
我的要求是不在运行时加载类,而是显示实现所需接口的类的用户列表,以便用户可以选择类和类名称可以传递给调度程序.这是Quartz调度程序,它最终将负责创建类的实例.
任何人都可以建议我如何实现上述目标,还是有任何其他更好的方法来实现我想要做的事情?
编辑
我浏览了ServiceLoader的文档,似乎为了实现一个服务,我必须在META-INF文件夹中创建一个具有实现类名称的文件,这使我认为如果我的API的用户想要20个不同的实现,他必须在文件中放入20个条目,这对我来说似乎为最终用户做了很多额外的工作,因为每个工作类将被创建用于执行特定的工作,并且可以有100个工作类.
如果我的假设错了,请纠正我.
如何在实现定义接口的类路径中发现运行时的类?
ServiceLoader非常适合(我认为,我还没有使用它),但我需要在Java 1.5中使用它.
假设java代码库有一个名为"com.example"的包.
在运行时,我们可以通过调用获取此包
Package p = Package.getPackage( "com.example" ); //(returns null)
Run Code Online (Sandbox Code Playgroud)
甚至可以通过调用获得所有包的列表
Packages[] ps = Package.getPackages();
Run Code Online (Sandbox Code Playgroud)
问题是 - 如果ClassLoader尚未从包中加载任何类,则它们将无法用于这些函数调用.我们可以通过首先强制加载包中的一个类来强制它加载包,如下所示:
this.getClass().getClassLoader().loadClass( "com.example.SomeClass" );
Package p = Package.getPackage( "com.example" ); //(returns non-null)
Run Code Online (Sandbox Code Playgroud)
但是,这很hacky并且需要提前知道属于该包的某个类的名称.
所以问题是 - 有没有办法按名称获取Package的实例,无论ClassLoader是否做了什么?关于类加载/包在这种情况下如何工作的假设是否准确?
我正在实现一个接口,现在我想在classpath中获得此接口的所有实现.这可能还是我应该做些什么呢?
我有一个功能,我希望为客户提供我们正在准备的软件模型 - 我想知道它是否是
我希望客户能够编写一个实现我的Computable界面的java类,并将其粘贴在某个预定的文件夹中.该文件夹将包含.java文件而不是.class文件.然后,在运行时,我希望我的程序搜索该文件夹并Computables从该文件夹中提取所有文件并将它们存储在从对象名称Computable到地图的地图中Computable.在Computable应该只有一个默认的构造和它的接口将仅具有一个称为方法compute它映射的阵列Object到Object.
我已经研究过Blaise Doughan关于这个问题的答案,但还有一个问题.
XmlJavaTypeAdapters允许您列出一堆XmlJavaTypeAdapter注释,每个注释管理JAXB如何将不可绑定类型映射到可绑定类型.
您可以在包级别使用此批注.执行此操作时,每个XmlJavaTypeAdapter注释都需要type()完全指定其属性.
似乎没有要求正在注释的包与要调整的不可绑定类型的包有任何关系.这很方便,也很好.
然而,这引出了我的下一个问题:如果注释包与被调整类型的包之间没有关系,那么JAXB如何发现包级XmlJavaTypeAdapters注释?换句话说,它是如何知道哪些包可以咨询潜在的XmlJavaTypeAdapters注释?我可以.jar在我的.ear文件lib目录中创建一个随机包,其中包含一个单独的,巨大的package-info类,该类使用所有不可绑定类型的所有适配器进行注释?
在Java中,有没有办法阻止扩展接口.
由于final无法添加到一个interface,我很想知道是否有任何方法,以防止扩展接口.
我看过帖子:
查看.jar文件的内容
以及
如何列出JAR文件中的文件?
但遗憾的是,我找不到一个好的解决方案来实际读取 JAR的内容(逐个文件).
此外,有人可以给我一个提示,或指向一个资源,我的问题在哪里讨论?
我只能想到一个不那么直接的方法来做到这一点:
我可以以某种方式将JAR资源列表转换为内部JAR URL列表,然后我可以使用openConnection()打开它.
java ×12
reflection ×5
interface ×2
api ×1
class ×1
classloader ×1
inheritance ×1
jar ×1
java-ee ×1
jaxb ×1
oop ×1
package ×1
plugins ×1
service ×1
subclass ×1