我可以替换已编译Java项目中的类文件吗?

我可以替换已编译Java项目中的类文件吗?,java,Java,这可能是,也应该是,一个被问了很多次,回答了很多次的问题,但我就是找不到答案 如果我有一个在服务器上运行的已编译应用程序,我可以在本地计算机上编译该应用程序,并将在本地计算机上编译的类与服务器上的类交换吗 换句话说,我是否可以将已编译且位于服务器端的文件替换为本地计算机上已编译且几乎相同的文件 由于服务器端的版本在其他文件中有一些硬编码的连接,我不知道所有的位置,我宁愿只交换我需要的一个文件,而不是对整个应用程序进行重新编译。是的,你可以这样做。此外,由于热点问题,该类甚至会在运行时重新加载,因

这可能是,也应该是,一个被问了很多次,回答了很多次的问题,但我就是找不到答案

如果我有一个在服务器上运行的已编译应用程序,我可以在本地计算机上编译该应用程序,并将在本地计算机上编译的类与服务器上的类交换吗

换句话说,我是否可以将已编译且位于服务器端的文件替换为本地计算机上已编译且几乎相同的文件


由于服务器端的版本在其他文件中有一些硬编码的连接,我不知道所有的位置,我宁愿只交换我需要的一个文件,而不是对整个应用程序进行重新编译。

是的,你可以这样做。此外,由于热点问题,该类甚至会在运行时重新加载,因此您不必重新启动服务器。这在开发周期中非常有用


但是要小心替换一个单独的类。如果该类引用了您环境中更改的其他类,则替换将在服务器上失败

我假设您所说的是“脱机”替换(我的意思是您可以重新启动服务器)

在这种情况下,以下解决方案可行: Java使用类路径变量。在这里,您定义了一系列JAR/文件夹,流程将在其中查找文件

因此,您可以执行以下操作:

  • 创建新类(它应该具有相同的名称并驻留在相同的包中)并编译
  • 在服务器上创建计划存储更新类的文件夹

  • 更新classpath变量(可能在应用程序的启动脚本中),使此文件夹显示在其他类之前

  • 重新启动服务器。现在,新类将在旧类之前解析并加载

  • 警告: 这适用于“独立”应用程序,通常也适用于那些不使用自定义类装入器的应用程序(例如,在应用程序服务器中就是这种情况)

    更复杂的解决方案可以基于定义类加载器,该加载器将查看这样一个文件夹(如我所述),并尝试从那里加载资源


    希望这对您有所帮助。

    您的问题的答案是肯定的,您可以替换类文件,但这有点复杂,因为您必须确保没有其他依赖项发生更改

    例如,如果要编译的类涉及更改其他类中使用的方法的方法签名,则还需要替换这些方法签名。只要public、protected或default方法的方法签名没有更改,您就可以了

    作为旁注,如果这是您经常做的事情,您将很快意识到为什么对象经常被传递到方法中而不是单个参数中

    public MyObject getObject(MyObject2 mySecondObject)
    
    vs

    当您需要向传递到方法中的对象添加新属性时,方法签名不会更改,但当您在方法签名本身上添加或删除参数时,它会在所有依赖项上产生连锁反应,需要您编译并替换这些类文件

    最后要强调的一点是,值得注意的是,对私有方法或私有变量,甚至对方法的定义所做的更改,对其他类文件没有影响。唯一重要的是,您维护了方法与其他类之间的契约,即输入和输出始终采用并返回相同的数据类型


    这突出了封装实例变量的重要性,以及如何对其他类隐藏这些依赖关系。

    它引入了一种部署风险,例如忘记本地类,这可能是不必要的,因为热插拔可以检测哪些类没有更改(由serialVersionID计算的类)。部署war可能需要更长的时间,但可以自动完成。JDK版本如何?我认为新的类文件必须使用与要替换的类文件相同的JDK进行编译。嗨@Cam,我几乎可以肯定你是对的,但老实说,我已经很久没有反编译过一些Java类文件了,我记不起来了
    public MyObject getObject(int a, int b, int c)