WEB开发网      婵犵數濮烽弫鍛婄箾閳ь剚绻涙担鍐叉搐绾剧懓鈹戦悩瀹犲闁汇倗鍋撻妵鍕箛閸洘顎嶉梺绋款儑閸犳劙濡甸崟顖氬唨闁靛ě浣插亾閹烘鈷掗柛鏇ㄥ亜椤忣參鏌″畝瀣暠閾伙絽銆掑鐓庣仭缁楁垿姊绘担绛嬪殭婵﹫绠撻、姘愁樄婵犫偓娴g硶鏀介柣妯款嚋瀹搞儱螖閻樺弶鍟炵紒鍌氱Ч瀹曟粏顦寸痪鎯с偢瀵爼宕煎☉妯侯瀳缂備焦顨嗗畝鎼佸蓟閻旈鏆嬮柣妤€鐗嗗▓妤呮⒑鐠団€虫灀闁哄懐濮撮悾鐤亹閹烘繃鏅濋梺闈涚墕濡瑩顢欒箛鏃傜瘈闁汇垽娼ф禒锕傛煕閵娿儳鍩f鐐村姍楠炴﹢顢欓懖鈺嬬幢闂備浇顫夊畷妯肩矓椤旇¥浜归柟鐑樻尭娴滃綊姊虹紒妯虹仸闁挎洍鏅涜灋闁告洦鍨遍埛鎴︽煙閼测晛浠滃┑鈥炽偢閹鈽夐幒鎾寸彇缂備緡鍠栭鍛搭敇閸忕厧绶炴俊顖滅帛濞呭洭姊绘担鐟邦嚋缂佽鍊垮缁樼節閸ャ劍娅囬梺绋挎湰缁嬫捇宕㈤悽鍛婄厽閹兼番鍨婚埊鏇㈡煥濮樿埖鐓熼煫鍥ュ劤缁嬭崵绱掔紒妯肩畺缂佺粯绻堝畷姗€濡歌缁辨繈姊绘担绛嬪殐闁搞劋鍗冲畷顖炲级閹寸姵娈鹃梺缁樻⒒閳峰牓寮崒鐐寸厱闁抽敮鍋撻柡鍛懅濡叉劕螣鐞涒剝鏂€闂佺粯鍔曞Ο濠囧吹閻斿皝鏀芥い鏃囨閸斻倝鎽堕悙鐑樼厱闁哄洢鍔屾晶顖炴煕濞嗗繒绠婚柡灞界Ч瀹曨偊宕熼鈧▍锝囩磽娴f彃浜炬繝銏f硾椤戝洨绮绘ィ鍐╃厵閻庢稒岣跨粻姗€鏌ㄥ☉妯夹fい銊e劦閹瑩顢旈崟顓濈礄闂備浇顕栭崰鏍礊婵犲倻鏆﹂柟顖炲亰濡茶鈹戦埄鍐ㄧ祷妞ゎ厾鍏樺璇测槈閵忕姈鈺呮煏婢跺牆鍔撮柛鏂款槺缁辨挻鎷呯粙搴撳亾閸濄儳鐭撶憸鐗堝笒閺嬩線鏌熼崜褏甯涢柡鍛倐閺屻劑鎮ら崒娑橆伓 ---闂傚倸鍊搁崐鐑芥倿閿旈敮鍋撶粭娑樺幘濞差亜鐓涢柛娑卞幘椤斿棝姊虹捄銊ユ珢闁瑰嚖鎷�
开发学院WEB开发Jsp 克服J2SE 1.3-1.4 的不兼容性 阅读

克服J2SE 1.3-1.4 的不兼容性

 2008-01-05 17:59:29 来源:WEB开发网 闂傚倸鍊搁崐椋庢濮橆兗缂氱憸宥堢亱闂佸湱铏庨崰鏍不椤栫偞鐓ラ柣鏇炲€圭€氾拷闂傚倸鍊搁崐椋庣矆娓氣偓楠炲鏁撻悩鎻掔€梺姹囧灩閻忔艾鐣烽弻銉︾厵闁规鍠栭。濂告煕鎼达紕校闁靛洤瀚伴獮鎺楀箣濠靛啫浜鹃柣銏⑶圭壕濠氭煙閻愵剚鐏辨俊鎻掔墛缁绘盯宕卞Δ鍐冣剝绻涘畝濠佺敖缂佽鲸鎹囧畷鎺戭潩閹典焦鐎搁梻浣烘嚀閸ゆ牠骞忛敓锟�婵犵數濮烽弫鍛婃叏椤撱垹绠柛鎰靛枛瀹告繃銇勯幘瀵哥畼闁硅娲熷缁樼瑹閳ь剙岣胯鐓ら柕鍫濇偪濞差亜惟闁宠桨鑳堕崝锕€顪冮妶鍡楃瑐闁煎啿鐖奸崺濠囧即閵忥紕鍘梺鎼炲劗閺呮稒绂掕缁辨帗娼忛埡浣锋闂佽桨鐒﹂幑鍥极閹剧粯鏅搁柨鐕傛嫹闂傚倸鍊搁崐椋庢濮橆兗缂氱憸宥堢亱闂佸湱铏庨崰鏍不椤栫偞鐓ラ柣鏇炲€圭€氾拷  闂傚倸鍊搁崐鐑芥嚄閼哥數浠氱紓鍌欒兌缁垶銆冮崨鏉戠厺鐎广儱顦崡鎶芥煏韫囨洖校闁诲寒鍓熷铏圭磼濡搫顫岄梺鍦拡閸嬪棝鎯€椤忓浂妯勯梺鍝勬湰濞叉ḿ鎹㈠┑濠勭杸闁哄洨濮烽悰銉╂⒒娴e搫甯跺鐟帮攻缁傚秴饪伴崼姘e亾閺冨牆绀冩い蹇庣娴滈箖鏌ㄥ┑鍡涱€楀褜鍠栭湁闁绘ɑ鐟ョ€氼喚绮绘ィ鍐╃厱妞ゆ劑鍊曢弸搴ㄦ煟韫囧鍔滈柕鍥у瀵潙螣閸濆嫬袝婵$偑鍊戦崹娲偡閳哄懎绠栭柍鈺佸暞閸庣喖鏌曢崶褍绨婚柟鍑ゆ嫹
核心提示:概要 实现java 众多API中的一个是一件困难的工作,你必须经常实现许多相互依靠的接口,克服J2SE 1.3-1.4 的不兼容性,对新特征的需求促进了最新Java API的创建,投资商们必须不断的更新他们的实现以跟上时代的需要,我现在可以正确的输入java.sql.Savepoint,在J2SE 1.3下,当复杂性和

  概要
  
  实现java 众多API中的一个是一件困难的工作。你必须经常实现许多相互依靠的接口。对新特征的需求促进了最新Java API的创建,投资商们必须不断的更新他们的实现以跟上时代的需要。当复杂性和持续修改可以理解甚至被看好时, API 版本的不兼容性迫使你为更新的版本保留独立的代码库,从而N次方增加你的受挫等级。本文演示了如何克服接口版本的不兼容性,制作可为多个API版本编译的代码库的进程。
  
  Java 已经添加了无数个API,像Java 数据库连接(JDBC),到它的标准库系列上。这可以帮助更广泛的用户使用API,因为可选软件包不必捆绑到配置上。对于编写这些流行的API的工作组来说,使用的越多他们的付出就越有价值。但是,当更新的Java版本运载最新的API,而最新的API依靠的类和方法是以前的Java版本所不能实现的时候,这些工作组希望他们的API仍然是可选的(与包括在Java的标准库系列内相反)。这样你忽然必须要保留实现的两个版本——一个编译老的API,另一个编译新的API。这就是发生在Java2平台标准版(J2SE)1.4中的JDBC API身上的事情。因为修改了JDBC API, java.sql.Connection 的一个实现不能在J2SE 1.3 和 1.4版本下编译。
  
  你可能发现你自己也处于与我一样的困境中:我需要实现JDBC 接口如 java.sql.Connection,但是我的代码需要在J2SE 1.3 和1.4下编译。我不想为J2SE 1.3 和1.4保留不同的源文件,所以我寻找更好的解决方法。
  
  不幸的是,当你需要Java编译器来完成编译时闻名的WORA (一次编写,各处运行)不包括WOCA (一次编写,各处编译)。幸运的是,使用Reflection API对代码做一些修改并且使用Ant 对编译做一些修改可以帮你走出困境。我能有一组.java 源文件和Ant来帮助我在J2SE 1.3 和 1.4两者之上编译代码。Ant答应我运行时修改.java文件,                               正确修改以便与编译时使用的Java版本兼容。但是在我阐述整个解决方案之前,我必须得说明整个问题。
  
  穷人的连接池
  
  两年前,我的公司需要一个JDBC连接池但是又买不起。那个时候,我们找不到好的免费的备选的东西,所以我们编写了一个内部的连接池。为了更好的追溯连接在整个我们的应用程序上是如何使用的,我们创建了com.icentris.sql.ConnectionWrapper,它实现java.sql.Connection和一些其他的可实现其他java.sql接口的包装者类。 包装者类只追踪我们应用程序内的数据库的使用并且传递方法调用到真正的JDBC资源处。
  
  当 J2SE 1.4 出来的时候,我们自然想要将一些我们的客户端程序移到它上面,这样他们就能从J2SE 1.4的许多改进中获益。但是,当然,我们仍然需要支持J2SE 1.3,因为那些客户端看不出有什么理由需要升级。我们生气的是, ConnectionWrapper和我们其他的JDBC包装者类不修改就不能在J2SE 1.4上编译。为了保持文章的简洁,我使用ConnectionWrapper来演示我应用到所有不能同时在J2SE 1.3和 1.4下编译的类的技巧。 为了遵循最新的JDBC API,我不得不添加几个方法到ConnectionWrapper上,这造成了两个大问题:
  
  1.因为我的包装者类需要通过方法调用,我不得不调用J2SE 1.3 sql 类中没有的方法。
  
  2.因为一些新方法依靠于新的类,我不得不依靠于J2SE 1.3 中没有的类。
  
  Reflection 来拯救
  
  一些代码样品最适合解释第一个问题。因为我的ConnectionWrapper包裹了java.sql.Connection,所有我的样品依靠于构造器中的realConnection实际变量 (粗体) 组:
  
  PRivate java.sql.Connection realConnection = null;
   
   public ConnectionWrapper(java.sql.Connection connection) {
    realConnection = connection;
   }
  
  为了看清楚我在没有不兼容问题的情况下做过什么,我们看看setHoldability(int) (到J2SE 1.4中的java.sql.Connection 的新方法):
  
  public void setHoldability(int holdability) throws SQLException {
    realConnection.setHoldability( holdability );
   }
  
  不幸的是,该代码在J2SE 1.3下不能编译因为 java.sql.Connection 没有我在J2SE 1.3才能调用的setHoldability()方法。但是要在J2SE 1.4下编译,我必须有一个setHoldability()方法可正确的实现该API. 要解决这个catch-22,我假设我的setHoldability() 方法只能在J2SE 1.4下编译,所以我可以使用Reflection API来调用该方法:
  
  public void setHoldability(int holdability) throws SQLException {
    Class[] argTypes = new Class[] { Integer.TYPE };
    Object[] args = new Object[] {new Integer(holdability)};
    callJava14Method("setHoldability", realConnection, argTypes, args);
   }
  
   public static Object callJava14Method(String methodName, Object instance,
   Class[] argTypes, Object[] args)
    throws SQLException
   {
    try {
     Method method = instance.getClass().getMethod(methodName, argTypes);
     return method.invoke(instance, args );
    } catch (NoSUChMethodException e) {
     e.printStackTrace();
     throw new SQLException("Error Invoking method (" + methodName + "): "
     + e);
    } catch (IllegalaccessException e) {
     e.printStackTrace();
     throw new SQLException("Error Invoking method (" + methodName + "): "
     + e);
    } catch (InvocationTargetException e) {
     e.printStackTrace();
     throw new SQLException("Error Invoking method (" + methodName + "): "
     + e);
    }
   }
  
  现在我有了setHoldability()方法,所以我可以在 J2SE 1.4下编译。我不直接调用我的java.sql.Connection 上以前不存在的方法,所以我能在J2SE 1.3下编译。我的 callJava14Method()方法使用 Reflection API调用该方法,然后包裹任何错误在SQLException里面,因为SQLException就是我给出的异常的全部。我将该策略用于所有新的J2SE 1.4方法,调用包裹了的方法,然后在 1.3下编译。现在我只需要解决第二个问题并且找出一条方法来依靠J2SE 1.3中不存在的类。
  
  Ant就是答案
  
  在J2SE 1.4中,java.sql.Connection依靠于新类java.sql.Savepoint。因为这个新类设置在 java.sql软件包内,你不可能将它添加到J2SE 1.3上。Java不答应添加任何第三组织的东西到java.* 或者 javax.*软件包中的核心类系列上。所以这也是对我的挑战:使用新的java.sql.Savepoint类来编写我的代码这样它就可以在J2SE 1.4下运行, 然后确保代码可在J2SE 1.3下编译,实际上,这个类在J2SE 1.3中不存在。简单,对吧?说“YES”的人都品行良好。好,至少,它简单得现在我已经找到答案了。
  
  首先,我将下列条件输入包括进来:
  
  // Comment_next_line_to_compile_with_Java_1.3
   import java.sql.Savepoint;
  
  然后为 Ant找到一条方法:当在J2SE 1.3下编译时可注释该输入。 简化之后, Ant 脚本核心部分为:
  
  <replace>
    <replacetoken>Comment_next_line_for_Java_1.3
  </replacetoken>
    <replacevalue>Comment_next_line_for_Java_1.3
  //</replacevalue>
   </replace>
  
  该 Ant 标记有几个选项——在下面的我的完整范例中你会看到更多——但是最重要的部分就是我搜索 然后用取代它。“
  
  ” 是用于"newline"的xml 实体。当在J2SE 1.4下编译时,Ant对源文件不做任何修改;并且在 J2SE 1.3下,重要语句被注释:
  
  // Comment_next_line_to_compile_with_Java_1.3
   //import java.sql.Savepoint;
  
  但是在必须依靠Savepoint 的类的体中仍有代码:
  
  public Savepoint setSavepoint(String name) throws SQLException { . . .
  
  再次,我只能期望可在J2SE 1.4下使用这些新方法,这样他们不必在J2SE 1.3下运行; 他们只需要编译。我发现:假如我的软件包中有一个Savepoint 类,我的代码不需要输入语句就可以编译。但是当输入语句没有注释的话(在J2SE 1.4编辑下),我的Savepoint 类会被忽略因为存在更非凡的输入。所以我创建了我自己的哑元类com.icentris.sql.Savepoint,它(java文章排斥它)可能是最短的有效类 :
  
  package com.icentris.sql;
  
   /** Dummy class to allow ConnectionWrapper to implement java.sql.Connection
    * and still compile under J2SE 1.3 and J2SE 1.4. When compiled
    * under J2SE 1.3, this class compiles as a placeholder instead of the
    * missing java.sql.Savepoint (not in J2SE 1.3). When compiled
    * under J2SE 1.4, this class is ignored and ConnectionWrapper uses the
    * java.sql.Savepoint that is new in J2SE 1.4.
    */
   public class Savepoint {}
  
  在J2SE 1.4下,我现在可以正确的输入java.sql.Savepoint。在J2SE 1.3下, Ant 注释输入行,这样我的代码中引用的 Savepoint正好在同一个软件包处于

Tags:克服 JSE 兼容性

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接