Java 当项目的所有访问修饰符都更改为public时,字节码中项目的语义是否会更改?

Java 当项目的所有访问修饰符都更改为public时,字节码中项目的语义是否会更改?,java,jvm,bytecode,semantics,access-modifiers,Java,Jvm,Bytecode,Semantics,Access Modifiers,假设我有一个可运行的jar(a.jar),里面有.class文件。我还有另一个可运行的jar(B.jar),它与A.jar相同,只是访问修饰符都更改为public(对于字段和方法)。是否有可能更改某些语义?它(B.jar)的工作方式是否与前一个(A.jar)完全相同?有什么危险 编辑示例: jar包含字节码(.class文件)。我使用asm库解析它,并将其所有修饰符更改为public。生成的jar是B.jar文件 一个可能的行为变化是私有方法不能覆盖超类中的方法。这意味着将子类方法更改为publ

假设我有一个可运行的jar(a.jar),里面有.class文件。我还有另一个可运行的jar(B.jar),它与A.jar相同,只是访问修饰符都更改为public(对于字段和方法)。是否有可能更改某些语义?它(B.jar)的工作方式是否与前一个(A.jar)完全相同?有什么危险

编辑示例:
jar包含字节码(.class文件)。我使用asm库解析它,并将其所有修饰符更改为public。生成的jar是B.jar文件

一个可能的行为变化是私有方法不能覆盖超类中的方法。这意味着将子类方法更改为public可能会潜在地更改运行时从虚拟调用调用的方法

来自JVM规范V115.4.5

实例方法mC可以覆盖另一个实例方法mA 以下情况之一是正确的:

mC与mA具有相同的名称和描述符

mC未标记为ACC_PRIVATE

以下情况之一是正确的:

mA标记为ACC_PUBLIC

mA标记为ACC_保护

mA标记为非ACC_公共、ACC_保护或ACC_私有,以及 (a)mA声明出现在同一运行时包中 作为mC的声明,或(b)如果mA在a类和mC中声明 在类C中声明,则存在在类C中声明的方法mB 类B,C是B的子类,B是a和mC的子类 可以覆盖mB,mB可以覆盖mA


jar包含字节码(.class文件)。例如,我使用asm库解析它,并将其所有修饰符更改为public。生成的jar是B.jar文件。(它还包含.class文件)好吧,有一件事会被破坏,那就是反射代码期望发生
IllegalAccessError
,因为它不再被抛出。也,列出带有某些修饰符的结构的反射代码的结果将发生变化。您试图做什么?我正在尝试静态内联某些调用站点,并且在不将访问修饰符更改为public的情况下,某些内联线将失败,并在运行修改后的jar时抛出非法访问,而不是使用InvokeSpecial调用的私有方法尽管如此?这意味着修改后的jar仍将使用invokeSpecial调用这些方法-接收器的动态类型仍然无关紧要,公共访问器也不会有什么不同;a、 foo();如果还有一个私有的B::foo并更改为public,则在上面的示例中会调用它。编辑:这也是无效的,因为javac不允许首先定义私有的B::foo(尝试分配较弱的访问权限;是公共的)
private
方法通过
invokspecial
调用,但包私有方法不被调用。因此,当您在类层次结构中有两个具有相同签名但在不同包中的包私有方法时,它们不会相互重写。当您将它们转到
公共
时,它们会这样做。此外,
invokespecial
仅在引用同一类中的方法时按预期方式工作。当你做内联时,正如你在一篇评论中所说的那样,无论如何都是行不通的。事实上,我已经放弃了某些包含invokeSpecial的内联。现在我需要对访问修饰符执行相同的操作。您提供的示例似乎是我需要处理的一个场景。霍尔格总是来救援!:)+1同样,自Java 11以来,私有方法通过invokevirtual调用。