代码之家  ›  专栏  ›  技术社区  ›  Andrew Sunil Kumar B M

如果父类/接口发生更改,类的字节码会发生更改吗?

  •  7
  • Andrew Sunil Kumar B M  · 技术社区  · 12 年前

    我试图确定是否需要重新编译构建链中的一些jar,例如,如果我有以下结构,jar 1在其“源代码”更改时编译,jar 2在其“来源代码”更改或jar 1重新编译时编译。

    罐子1:

    public class Foo /* impl*/
    

    罐子2:

    public class Bar extends Foo /*impl*/
    

    假设两个班级之间的合同没有改变 ,即向接口添加抽象方法或方法等。

    我需要重新编译jar 2吗?例如,如果对Foo中的私有方法进行了一些更改,Bar是否需要重新编译?

    我试着通过比较两个类的字节码来测试这一点,在一个类中更改了一堆之后,正如预期的那样,它没有更改。然而,我的同事坚持认为,他们遇到过这样的情况,即使合同没有改变,他们也必须重新编译所有内容才能工作,但他们不记得原因是什么。。。因此,我有责任证明这不应该是必要的。 是否存在对超类进行更改需要重新编译子类的情况,即使两者之间的接口保持不变?

    3 回复  |  直到 12 年前
        1
  •  6
  •   irreputable    12 年前

    比方说 Foo 由开源组织发布;有成千上万的子类 Foo公司 由多家公司实施。

    现在,如果对 Foo公司 ,并且新版本是以二进制形式发布的,所有公司都应该重新编译他们的代码吗?当然不是。(好吧,我们总是重新编译所有代码,但这不是必需的—— Foo公司 可以简单地插入而不会引起任何问题)

    这是二进制兼容性的问题,您可以检查规范以确保 Foo公司 是安全的。看见 http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html

        2
  •  3
  •   AlexR    12 年前

    在一般情况下,您必须重新编译依赖类。但是,如果您没有更改的任何方法或字段 Foo 由使用 Bar 您不必重新编译 酒吧 什么时候 Foo公司 已更改。

    例如,如果 Foo公司 had方法 protected int foo() 由呼叫 酒吧 但你把签名改成了 protected String foo() 或将其可见性更改为 private 你必须重新编译 酒吧 .在这种情况下 酒吧 无法编译:您必须更改其代码。

    但是,如果 酒吧 不使用方法 foo() 或者如果只有的实现细节 foo() 已更改,您可以使用 酒吧 而无需重新编译。

        3
  •  2
  •   ijrandom    12 年前

    当然不是。你可以使用打包在jar文件中的框架(其中包含很多像Foo这样的类),而不需要从源代码编译它们。但你需要绝对确定合同没有被直接或间接地改变。一些间接变化的例子:

    public class Foo { //v1
        public static final int CONSTANT = 1;         
    }
    
    public class Foo { //v2
        public static final int CONSTANT = 2;         
    }
    
    public class Bar extends Foo {
        private int a(int value) {
            switch (value) {
                case CONSTANT:
                    return 1;
            }
            return 2;
        }
    }
    

    如果不重新编译类Bar,它仍将使用值1。

    推荐文章