熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> JSP教程 >> 正文

Java應用的動態擴展

2013-11-15 09:47:35  來源: JSP教程 

  這裡所謂的可擴展應用是指這樣的編程語言或者系統它可以在不修改現有系統整體或任意一部分功能的情況下擴展自身的功能對於傳統的編程語言比如CobolCC++如果要為它們的應用增加新功能程序員必須重新編輯編譯和發布程序因為這些語言都是靜態鏈接的語言不具備動態添加功能的機制(也就是說生成執行代碼的時候所有的程序代碼必須事先准備妥當)Java應用的可擴展能力突破了這些限制
  
  Java應用的可擴展功能包含了允許動態地定義新的數據類型以及允許用戶插入自己的程序例程的能力這一切是如何實現的呢?下面我們通過實例來了解具體的實現過程
  
  普通應用的擴展
  
  在Java中擴展性源於繼承具體手段或者是擴展一個類或者是實現一個接口Java接口的主要用途就在於此(Java接口定義了一組方法但不包含實現實現某個接口的類必須實現該接口定義的所有方法因而也就遵循某種確定的行為模式
  
  為什麼說這個功能對於普通程序來說也很重要呢?如果一個程序是可以動態擴展的用戶就不必再為了添加新功能而去修改源程序這就避免了搞亂原有的代碼使得用戶能夠專注於自己的那一部分代碼此外程序不必為了引入新功能而重新啟動這對於那些需要不間斷運行的程序來說無疑是一個福音
  
  為進一步了解Java程序的動態擴展技術我們來看一個例子一家快速增長的保險公司想要用計算機管理它的報價系統這家公司現有兩個產品人壽保險(lifecare)和醫療保險(medicare)根據保額期限客戶年齡和保險產品的不同月保險費用的計算方法也不同系統應該能夠在不修改原有代碼的情況下引入保險公司推出的其他產品為現有產品設計的類模型如圖一所示
   
  當一個客戶試圖獲取某種保險產品的報價時系統創建一個對應該產品類型的對象調用該對象的calculatePremium()方法根據指定產品的計算方法計算出保險費用系統利用一個XML文件(或屬性文件)描述現有產品信息比如保險產品的名稱和相應的類名稱XML文件如Listing 所示
  
  【Listing 描述產品信息的XML文件】
   
  系統從XML文件讀取指定產品的類的全稱動態地創建對象然後系統調用calculatePremium()根據指定的保額期限和客戶年齡按照特定產品的計算邏輯計算出精確的保險費
  現在我們來看看系統如何動態地裝入對象在把類裝入內存和創建特定產品類型的對象時系統用到了Java類庫javalangClassClass類的實例或者代表著Java應用中的一個類或者代表著一個接口在後台Java虛擬機(JVM)常常利用Class類操作Java類然而用戶程序也同樣可以通過Class類的實例操作Java類請參見Listing 的Class類摘要
  
  【Listing Class類概要】
  
  public final class javalangClass extends
  
  javalangObject
  
  {
  
  public static Class forName(String className)
  
  public static Class forName(
  
  String name boolean initialize ClassLoader loader)
  
  public Class[] getClasses()
  
  public ClassLoader getClassLoader()
  
  public Class getComponentType()
  
  public Constructor getConstructor(Class[] parameterTypes)
  
  public Constructor[] getConstructors()
  
  public Class[] getDeclaredClasses()
  
  public Constructor getDeclaredConstructor(
  
  Class[] parameterTypes)
  
  public Constructor[] getDeclaredConstructors()
  
  public Field getDeclaredField(String name)
  
  public Field[] getDeclaredFields()
  
  
  public Method getDeclaredMethod(String name Class[]
  
  parameterTypes)
  
  public Method[] getDeclaredMethods()
  
  public Class getDeclaringClass()
  
  public Field getField(String name)
  
  public Field[] getFields()
  
  public Class[] getInterfaces()
  
  public Method getMethod(
  
  String name Class[] parameterTypes)
  
  public Method[] getMethods()
  
  public int getModifiers()
  
  public String getName()
  
  public Package getPackage()
  
  public ProtectionDomain getProtectionDomain()
  
  public URL getResource(String name)
  
  public InputStream getResourceAsStream(String name)
  
  public Object[] getSigners()
  
  public Class getSuperclass()
  
  public boolean isArray()
  
  public boolean isAssignableFrom(Class cls)
  
  public boolean isInstance(Object obj)
  
  public boolean isInterface()
  
  public boolean isPrimitive()
  
  public Object newInstance()
  
  public String toString()
  
  }
  在這裡我們感興趣的主要是forName()方法和newInstance()方法靜態方法forName()返回和指定類名字關聯的Class對象它通過類裝入器把類裝入到執行程序類名字參數可以是classpath中存在的任意一個類如果不能找到指定類則forName()方法拋出ClassNotFoundException異常newInstance()方法為Class對象代表的類新建一個實例newInstance()方法也利用類的不帶參數的構造函數創建新對象因此該類必須有一個不帶參數的構造函數如果newInstance()方法由於任何原因不能實例化一個類它將拋出InstantiationException異常如果不能訪問該類或它的構造函數則拋出IllegalAccessException異常Listing 顯示了Product接口和它的實現MediCareLifeCare
  
  【Listing Product接口及其實現】
  
  
  // Productjava
  
  // Product接口
  
  package comtestdynamic;
  
  
  public interface Product
  
  {
  
  public float calculatePremium(
  
  float facevalueint term int age);
  
  }
  
  
  // MediCarejava
  
  // Product的一個實現
  
  package comtestdynamic;
  
  
  public class MediCare implements Product
  
  {
  
  public float calculatePremium(
  
  float facevalue int term int age)
  
  {
  
  float premium;
  
  // 計算保險費
  
  //
  
  return premium;
  
  }
  
  }
  
  
  // LifeCarejava
  
  // Product的一個實現
  
  package comtestdynamic;
  
  
  public class LifeCare implements Product
  
  {
  
  public float calculatePremium(
  
  float facevalue int term int age)
  
  {
  
  float premium;
  
  // 計算保險費(不同的保險產品計算方法不同)
  
  //
  
  return premium;
  
  }
  
  }
  當用戶詢問報價時報價系統根據保險產品的名字裝入並實例化產品類下面我們用兩個方法實現裝入和調用代碼GetProductFromName根據指定的產品名字生成合適的產品對象makeQuote()方法計算保險費Listing 顯示了它們的代碼
  
  【Listing 生成產品對象計算保險費】
  
  public Object GetProductFromName(String productName)
  
  {
  
  // 待裝入對象的類名稱
  
  String className = null;
  
  // 利用XML分析庫orgxmlsax
  
  // 從XML文件獲取產品的相應類名稱
  
  //
  
  
  // 假定類名字對應正確的產品例如
  
  // ComtestdynamicMediCare
  
  try
  
  {
  
  Object o = null;
  
  o = ClassforName(className)newInstance();
  
  }
  
  //catch(ClassNotFoundException e){}
  
  //catch(InstantiationException e){}
  
  //catch(IllegalAccessException e){}
  
  catch( Exception e )
  
  {
  
  eprintStackTrace();
  
  }
  
  return o;
  
  }
  
  // makeQuote方法無返回值
  
  public void makeQuote()
  
  {
  
  String productName;
  
  float faceValue premium ;
  
  int faceValue age;
  
  
  // 從應用的用戶界面獲取所有參數包括
  
  // 產品名稱期限保額年齡
  
  // (有效的產品可以
From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19125.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.