国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Java實例化類詳解

2019-11-26 14:29:25
字體:
來源:轉載
供稿:網友

Java 中實例化類的動作,你是否還是一成不變 new 對應對象呢?

    經手的項目多了,代碼編寫量自然會增加,漸漸的會對設計模式產生感覺。

    怎樣使書寫出來的類實例化動作,高內聚,低耦合,又兼具一定的擴展能力呢?

    本文試圖從幾段鮮活的代碼入手,給大家呈現不一樣的 Java 實例化類。

    下面代碼取自 com.google.zxing 源碼實現:

public BitMatrix encode(String contents, BarcodeFormat format, int width, int height, Map<EncodeHintType, ?> hints) throws WriterException {    Object writer;    switch(format.ordinal()) {    case 1:      writer = new AztecWriter();      break;    case 2:      writer = new CodaBarWriter();      break;    case 3:      writer = new Code39Writer();      break;    case 4:    case 10:    case 13:    case 14:    default:      throw new IllegalArgumentException("No encoder available for format " + format);    case 5:      writer = new Code128Writer();      break;    case 6:      writer = new DataMatrixWriter();      break;    case 7:      writer = new EAN8Writer();      break;    case 8:      writer = new EAN13Writer();      break;    case 9:      writer = new ITFWriter();      break;    case 11:      writer = new PDF417Writer();      break;    case 12:      writer = new QRCodeWriter();      break;    case 15:      writer = new UPCAWriter();      break;    case 16:      writer = new UPCEWriter();    }    return ((Writer)writer).encode(contents, format, width, height, hints);  }

其中的 BarcodeFormat 是這樣的:

public enum BarcodeFormat {  AZTEC,  CODABAR,  CODE_39,  CODE_93,  CODE_128,  DATA_MATRIX,  EAN_8,  EAN_13,  ITF,  MAXICODE,  PDF_417,  QR_CODE,  RSS_14,  RSS_EXPANDED,  UPC_A,  UPC_E,  UPC_EAN_EXTENSION;  private BarcodeFormat() {  }}

源碼提供的功能是將信息通過幾種不同類型條形碼 Wirter 輸出為位矩陣,然后輸出到圖片上面,形成隨處可見的各種類型的條形碼。

BitMatrix bitMatrix = new MultiFormatWriter().encode(_text, BarcodeFormat.QR_CODE, qrcodeWidth, qrcodeHeight, hints);
MatrixToImageWriter.writeToFile(bitMatrix, qrcodeFormat, QrcodeFile);

源碼作者在這里使用了JDK 1.5  中引入的新特性 enum 枚舉類,編寫了BarcodeFormat類,其中定義了不同類型的條形碼的屬性。

調用 MultiFormatWriter.encode()  根據入參 BarcodeFormat.xx 在枚舉類中的序號,來實例化具體的類。

    switch(format.ordinal()) {    case 1:      writer = new AztecWriter();      break;    case 2:      writer = new CodaBarWriter();      break;    case 3:      writer = new Code39Writer();      break;    ...............

這些條形碼 Writer 類,同時都實現了抽象接口 Writer 的 兩個encode()方法。

public interface Writer {  BitMatrix encode(String var1, BarcodeFormat var2, int var3, int var4) throws WriterException;  BitMatrix encode(String var1, BarcodeFormat var2, int var3, int var4, Map<EncodeHintType, ?> var5) throws WriterException;}

 具體的條形碼 Wirter 類內部根據不同類型的條形碼規則,進行不同的邏輯。

使用者不需要過多的關注內部的實現,需要產生什么樣子的條形碼,入參選用合適的條形碼類型即可,筆者上述的例子里面實現的是二維碼。

      在來看經典 MVC 框架 Webwork 動態實例化類的一段方法代碼:

  private static Configuration getDefaultConfiguration () {      if (defaultImpl == null) {        defaultImpl = new DefaultConfiguration();        try {          String className = getString("webwork.configuration");          if (!className.equals(defaultImpl.getClass().getName())) {            try {              defaultImpl = (Configuration) ObjectFactory.getObjectFactory().buildBean(Thread.currentThread().getContextClassLoader().loadClass(className));            } catch (Exception e) {              LOG.error("Could not instantiate configuration", e);            }          }          return defaultImpl;        } catch (IllegalArgumentException localIllegalArgumentException) {        }      }    }

源碼取自 webwork-core,可能很多看客老爺沒有聽聞 Webwork, 但是對 Struts 應該是如雷貫耳,Struts2 核心改寫自 Webwork。

上述源碼提供的功能為實例化用戶自己定義的 配置文件讀取類,該定義是在配置文件當中。

源碼作者在這里使用 Thread.currentThread().getContextClassLoader().loadClass(className) 線程中類加載器,動態實例化自定義配置文件讀取類,可謂是效率最高的一種做法。
類加載器的委托鏈:SystemClassloader -> ExtensionClassloader -> BootstrapClassloader
委派鏈左邊的ClassLoader就可以很自然的使用右邊的ClassLoader所加載的類,類加載的機制為判斷自已是否加載該類,沒有在詢問上級。

而這三個類加載器分別對應著編譯器去尋找類文件的優先級別和不同的路徑:

  1. BootClassLoader  它是用C++編寫的,從%jre%/lib目錄中加載類,或者運行時用-Xbootclasspath指定目錄來加載。是編譯器最優先尋找class的地方
  2. ExtClassLoader  從%jre%/lib/ext目錄加載類,或者運行時用-Djava.ext.dirs制定目錄來加載。是編譯器次優先尋找class的地方
  3. SystemClassloader 也就是我們常說的AppClassloader ,它對應當前路徑,所以也是編譯器默認找class的地方。

平時項目中使用的 Class.forname() 會從 BootstrapClassloader 開始詢問,是最消耗資源的。

源碼作者在這里采用線程類加載器,對應為 SystemClassloader ,效率無疑是最高的。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 内丘县| 赤峰市| 商丘市| 永福县| 平南县| 内黄县| 长岭县| 永定县| 乌审旗| 辉县市| 上杭县| 蚌埠市| 龙口市| 荆门市| 丹东市| 南皮县| 林口县| 边坝县| 井冈山市| 抚松县| 桓仁| 淮阳县| 鄂伦春自治旗| 报价| 宜黄县| 饶平县| 镇安县| 鄂托克前旗| 汤原县| 南皮县| 永胜县| 大关县| 梧州市| 抚顺市| 平武县| 乐业县| 柯坪县| 萍乡市| 郎溪县| 红桥区| 瓦房店市|