二进制兼容原理 - C/C++ && Java

本文探讨了二进制兼容性在软件开发中的重要性,特别是对于类库更新的影响。在C++中,二进制不兼容可能导致组件之间的协调出现问题,而Java通过延迟绑定实现了二进制兼容,允许类的某些修改不影响程序执行。然而,不恰当的类修改仍可能导致运行时错误,如`AbstractMethodError`。理解并遵循二进制兼容的规则对于保证软件的稳定性和兼容性至关重要。
摘要由CSDN通过智能技术生成

       从某种意义上来讲,现代软件已经不是数据结构与算法的简单聚合,更多的是构件开发以及基于体系结构的构件组装.而这些构件,通常都是由不同厂商、作者开发的共享组件,所以组件管理变得越来越重要。在这方面,一个极其重要的问题是类的不同版本的二进制兼容性,即一个类改变时,新版的类是否可以直接替换原来的类,却不至于损坏其他由不同厂商/作者开发的依赖于该类的组件?

       在C++中,对域(类变量或实例变量)的访问被编译成相对于对象起始位置的偏移量,在编译时就确定,如果类加入了新的域并重新编译,偏移量随之改变,原先编译的使用老版本类的代码就不能正常执行( 也许有人会认为这是C++要比Java的快的一个原因,根据数值性偏移量寻找方法肯定要比字符串匹配快。这种说法有一定道理,但只说明了类刚刚装入时的情况,此后Java的JIT编译器处理的也是数值性偏移量,而不再靠字符串匹配的办法寻找方法,因为类装入内存之后不可能再改变,所以这时的JIT编译器根本无须顾虑到二进制兼容问题。因此,至少在方法调用这一点上,Java没有理由一定比C++慢),不仅如此,虚函数的调用也存在同样的问题。这些我们都称之为二进制不兼容,与之对应的是源码不兼容,如修改成员变量名字等.

       C++环境通常采用重新编译所有引用了被修改类的代码来解决问题。在Java中,少量开发环境也采用了同样的策略,但这种策略存在诸多限制。例如,假设有人开发了一个程序P,P引用了一个外部的库L1,但P的作者没有L1的源代码;L1要用到另一个库L2。现在L2改变了,但L1无法重新编译,所以P的开发和更改也受到了限制。为此,Java引入了二进制兼容的概念—如果对L2的更改是二进制兼容的,那么更改后的L2、原来的L1和现在的P能够顺利连接,不会出现任何错误。

      首先来看一个简单的例子。Authorization和Customer类分别来自两个不同的作者,Authorization提供身份验证和授权服务,Customer类要调用Authorization类。    

package com.author1;
public class Authorization {
 public boolean authorized(String userName) {
  return true;
 }
}

package com.author2;
import com.author1.*;
class Customer{
 public static void main(String arg[]) {
  Authorization auth = new Authorization();
  if(
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值