zoukankan      html  css  js  c++  java
  • Java 二进制兼容性

      现在的软件越来越依赖于不同厂商、作者开发的共享组件,组件管理也变得越来越重要。在这方面,一个极其重要的问题是类的不同版本的二进制兼容性,即一个类改变时,新版的类是否可以直接替换原来的类,却不至于损坏其他由不同厂商/作者开发的依赖于该类的组件?

      Java二进制兼容性概念的主要目标是推动Internet上软件的广泛重用,同时它还避免了大多数C++环境面临的基础类脆弱性问题——例如,在C++中,对域(数据成员或实例变量)的访问被编译成相对于对象起始位置的偏移量,在编译时就确定,如果类加入了新的域并重新编译,偏移量随之改变,原先编译的使用老版本类的代码就不能正常执行;虚拟方法调用也存在同样的问题。
      
      C++环境通常采用重新编译所有引用了被修改类的代码来解决问题。在Java中,少量开发环境也采用了同样的策略,但这种策略存在诸多限制。例如,假设有人开发了一个程序P,P引用了一个外部的库L1,但P的作者没有L1的源代码;L1要用到另一个库L2。现在L2改变了,但L1无法重新编译,所以P的开发和更改也受到了限制。
      
      为此,Java引入了二进制兼容的概念——如果对L2的更改是二进制兼容的,那么更改后的L2、原来的L1和现在的P能够顺利连接,不会出现任何错误。
      
      首先来看一个简单的例子。Authorization和Hello类分别来自两个不同的作者,Authorization提供身份验证和授权服务,Hello类要调用Authorization类。

    1 package com.author1;
    2 public class Authorization {
    3     public boolean authorized(String userName) {
    4         return true;
    5     }
    6 }
     1 package com.author2;
     2 import com.author1.*;
     3 
     4 public class Hello {
     5     public static void main(String arg[]) {
     6         Authorization auth = new Authorization();
     7         if (auth.authorized("MyName")) {
     8             System.out.println("您已经通过验证");
     9         } else {
    10             System.out.println("您未能通过身份验证");
    11         }
    12     }
    13 }                 

      现在author1发布了Authorization类的2.0版,Hello类的作者author2希望在不更改原有Hello类的情况下使用新版的Authorization类。2.0版的Authorization要比原来的复杂不少:

    public class Authorization {
        public Token authorized(String userName, String pwd) {
            return null;
        }
    
        private boolean determineAuthorization(String userName, String pwd) {
            return true;
        }
    
        public boolean authorized(String userName) {
            return true;
        }
    
        public class Token {
        }
    }

      作者author1承诺2.0版的Authorization类与1.0版的类二进制兼容,或者说,2.0版的Authorization类仍旧满足1.0版的Authorization类与Hello类的约定。显然,author2编译Hello类时,无论使用Authorization类的哪一个版本都不会出错——实际上,如果仅仅是因为Authorization类升级,Hello类根本无需重新编译,同一个Hello.class可以调用任意一个Authorization.class。

      这一特性并非Java独有。UNIX系统很早就有了共享对象库(.so文件)的概念,Windows系统也有动态链接库(.dll文件)的概念,只要替换一下文件就可以将一个库改换为另一个库。就象Java的二进制兼容特性一样,名称的连接是在运行时完成,而不是在代码的编译、连接阶段完成,而因它也同样拥有Java二进制兼容性所具有的优点,例如修改代码时只需重新编译一个库,便于对程序的某一部分进行修改。但是,Java的二进制兼容性还有其独特的优势:

    • Java将二进制兼容性的粒度从整个库(可能包含数十、数百个类)细化到了单个的类。
    • 在C/C++之类的语言中,创建共享库通常是一种有意识的行为,一个应用软件一般不会提供很多共享库,哪些代码可以共享、哪些代码不可共享都是预先规划的结果。但在Java中,二进制兼容变成了一种与生俱来的天然特性。
    • 共享对象只针对函数名称,但Java二进制兼容性考虑到了重载、函数签名、返回值类型。
    • Java提供了更完善的错误控制机制,版本不兼容会触发异常,但可以方便地捕获和处理。相比之下,在C/C++中,共享库版本不兼容往往引起严重问题。

      Here is a list of some important binary compatible changes that the Java programming language supports:

      •   Reimplementing existing methods, constructors, and initializers to improve performance.
      •   Changing methods or constructors to return values on inputs for which they previously either threw exceptions that normally should not occur or failed by going into an infinite loop or causing a deadlock.
      •   Adding new fields, methods, or constructors to an existing class or interface.
      •   Deleting private fields, methods, or constructors of a class.
      •   When an entire package is updated, deleting default (package-only) access fields, methods, or constructors of classes and interfaces in the package.
      •   Reordering the fields, methods, or constructors in an existing type declaration.
      •   Moving a method upward in the class hierarchy.
      •   Reordering the list of direct superinterfaces of a class or interface.
      •   Inserting new class or interface types in the type hierarchy.

  • 相关阅读:
    BZOJ 1051: [HAOI2006]受欢迎的牛( tarjan )
    BZOJ 2208: [Jsoi2010]连通数( DFS )
    js效果-鼠标提示框
    CSS-背景
    CSS-文本
    tomcat 安装 for Mac
    CSS选择器基础
    POJ3349-Snowflake Snow Snowflakes-Hash
    数据库的三大设计范式
    HDU5120-Intersection-两个圆环相交面积
  • 原文地址:https://www.cnblogs.com/kesuns/p/12703716.html
Copyright © 2011-2022 走看看