Java 如何在类加载时运行代码?

Java 如何在类加载时运行代码?,java,classloader,Java,Classloader,在Java中加载任何类时,是否有一种可行的方法来运行我自己的代码,而不必强制用户使用自定义类加载器显式地手动加载所有类 不必过多地讨论细节,只要实现某个接口的类读取了它与另一个类链接的注释,并将该注释对提供给第三个类 编辑:见鬼,我将转到详细信息:我正在做一个事件处理库。我所做的是让客户机代码执行它们自己的侦听器/事件对,它们需要作为一对在我的库中注册。(嗯,那毕竟没多久) 进一步编辑:目前客户机代码需要手动注册这对类/接口,这非常有效。我的目的是将其自动化,我认为用注释链接这两个类会有所帮助。

在Java中加载任何类时,是否有一种可行的方法来运行我自己的代码,而不必强制用户使用自定义类加载器显式地手动加载所有类

不必过多地讨论细节,只要实现某个接口的类读取了它与另一个类链接的注释,并将该注释对提供给第三个类

编辑:见鬼,我将转到详细信息:我正在做一个事件处理库。我所做的是让客户机代码执行它们自己的侦听器/事件对,它们需要作为一对在我的库中注册。(嗯,那毕竟没多久)

进一步编辑:目前客户机代码需要手动注册这对类/接口,这非常有效。我的目的是将其自动化,我认为用注释链接这两个类会有所帮助。下一步,我想摆脱需要始终保持注册列表最新的客户机代码


PS:静态块不行,因为我的接口被绑定到一个库中,客户端代码将创建更多的接口。因此,抽象类也不能这样做,因为它必须是一个接口。

如果您想将行为建立在接口上,可以在该接口中使用静态初始值设定项

public interface Foo{

    static{
        // do initializing here
    }

}
我并不是说这是一个好的实践,但它肯定会在第一次加载一个实现类时初始化

更新:接口中的静态块是非法的。改用抽象类

参考资料:

  • (Sun Java教程)

但是,如果我没有弄错的话,您希望每个实现类初始化一次。这将是棘手的。使用基于接口的解决方案绝对不能做到这一点。您可以使用一个具有动态初始值设定项(或构造函数)的抽象基类来执行此操作,该类检查请求的映射是否已经存在,如果不存在,则添加它,但在构造函数中执行此类操作相当困难

我想说,最干净的选择是在构建时生成代码(使用apt进行注释处理或使用asm等工具进行字节码分析),或者在类加载时使用代理动态创建映射


啊,多投入。很好。因此,客户机使用您的库并提供基于注释的映射。然后我想说,您的库应该提供一个初始化方法,客户机代码可以在其中注册类。大概是这样的:

YourLibrary.getInstance().registerMappedClasses(
    CustomClass1.class,
    CustomClass2.class,
    CustomClass3.class,
    CustomClass4.class
)
或者,更好的是,包扫描机制(可以找到实现此功能的示例代码):


无论如何,基本上没有办法避免让您的客户机执行此类工作,因为您无法控制他们的构建过程或类加载器(但您当然可以为类加载器或构建配置提供指南)。

如果您希望在任何类加载上运行某些代码,您应该:

  • 覆盖类加载器,在loadClass方法中添加您自己的自定义代码(不要忘记在自定义代码之后或之前转发到父类加载器)
  • 将此自定义类加载器定义为系统的默认类加载器(在这里您了解了如何操作:)
  • 运行并检查它

  • 取决于您所处的环境类型,并非所有的类都可以通过自定义类加载器加载(一些实用程序包使用自己的CL,一些JavaEE容器使用特定的类加载器处理某些特定的区域,等等),但这是一种对您的要求的近似

    嗯,你试过使用静态初始化块吗?(只是在OP中添加了更多信息)静态块或抽象类不行。你理解的对-这将是每个客户端代码接口完成的。我目前正在做注册的事情(除了我还没有注释,它们是在客户端定义的对中注册的),效果很好。我想把它自动化。但这种包扫描方法似乎很有吸引力(除了更难进行的重构)。我来看看这个解决方案。唉,这里也不接受。放松点,你一小时前才问这个问题,现在什么都不需要接受。顺便说一句:即使你这样做了,你也可以稍后取消接受答案。这真的会被编译吗?@SeanPatrickFloyd真的吗?您不能在
    界面
    内使用
    静态
    块。你试过了吗?谢谢。我来试一试。不过,我现在还不会接受这个答案。
    YourLibrary.getInstance().registerMappedClassesFromPackages(
        "com.mycompany.myclientcode.abc",
        "com.mycompany.myclientcode.def"
    )