二进制兼容性

来源:互联网 发布:网络不稳定怎么回事 编辑:程序博客网 时间:2024/05/20 06:07

一、概念:如果一个基于老版本开发的程序,在不需要重新编译的前提下,可以和新版本类库进行正常连接并执行,那么这种情况可以称作二进制兼容。

二、Java二进制兼容

1、对于java语言来说,需要去了解Class文件的格式,以及Java虚拟机如何加载Class文件的。实际上,Class文件的格式与Java源代码的格式非常相似。第一个不同之处在于源代码中的 ‘*’式导入是不存在的,因为在Class文件中,所有的名称必须是全名(完全限定名),同样,一个字段或方法的名称所包含的不仅仅是源代码中的名称,而且使用了真是的类名和方法名称。对于一个方法,就表示所有的参数和返回值都使用全名。因此,在一个类文件中,其实可以有两个同名方法,即使它们的参数名称完全相同,只要返回值不同,那就是合法的。

/** 这段Java代码不能编译通过,但如果用二进制的方式,这种结构却是存在的。可以通过直接修改二进制文件实现 */public abstract class DoubleReturnType{    public abstract String getName(int x);    public abstract StringBuffer getName(int x);}

2、虚方法表:当定义了一个包含非final方法的类时(private和static方法默认为final,不能覆盖),虚拟机就会自动创建一张“虚方法表”。运行时,方法的名称、参数描述以及返回值,还有代码运行时方法被调用的真实入口地址,这些内容都会通过这张表进行映射。当创建子类时,会为子类创建一张相同的表,只是填入的内容不同,它会用一些新的指针来指向某些被覆盖方法在调用时的地址。当方法代码被调用时,会去检查这张虚方法表,以便从中查找到正确的方法入口,然后再跳转到相应的地址,执行相应的代码。

Java基础类的虚方法表示例方法ObjectStringNumberInteger"equals"Object.equalsString.equalsObject.equalsInteger.equals"toString"Object.toStringString.toStringObject.toStringInterger.toString"finalize"Object.finalizeObject.finalizeObject.finalizeObject.finalize3、版本控制:如果定义了一个static的public常量,而且声明为final,不管是String还是int,那么它的值是不能通过引用的方式来使用的,而是在编译期间将其值复制到具体的二进制Class文件中。利用这一特点,JBuilder使用它来进行了版本控制。

public abstract class API{    public static final int VERSION=1;    protected API(){        System.err.println("Initializing version " + VERSION);        init(API.VERSION);        System.err.println("Property initialized: " + this);    }    protected abstract void init(int version) throws IllegalStateException;}public class Impl extends API{    protected void init(int version) throws IllegalStateException{        if(version != API.VERSION){            throw new IllegalStateException("Wrong API version error!");        }    }}
在版本1时将上面两个类同时编译,运行正常,当抽象类升级为版本2,即VERSION=2后,如果不重新编译实现类,那么将会抛出异常。

三、C++与java:在C++中,对域(数据成员或实例变量)的访问被编译成相对于对象起始位置的偏移量,在编译时就确定,如果类加入了新的域并重新编译,偏移量随之改变,原先编译的使用老版本类的代码就不能正常执行;虚拟方法调用也存在同样的问题。Java 实际上把 C/C++ 的 linking 这一步骤推迟到 class loading 的时候来做。就不存在“不能增加虚函数”,“不能修改 data member” 等问题。在 Java 里边用面向 interface 编程远比 C++ 更通用和自然,也没有上面提到的“僵硬的接口”问题。

摘录引用:1、软件框架设计的艺术

           2、http://blog.csdn.net/deyili/article/details/6442687

           3、http://blog.csdn.net/greencacti/article/details/7588812

0 0
原创粉丝点击