一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - Java實例化類詳解

Java實例化類詳解

2020-04-11 14:32hebedich JAVA教程

學習JAVA這門面向對象的語言,實質就是不斷地創建類,并把類實例化為對象并調用方法。對于初學JAVA的人總搞清楚對象是如何實例化的,假如類之間存在繼承關系,那就更糊涂了。下面我們通過兩個例題來說明對象的實例化過程。

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

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

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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 是這樣的:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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 在枚舉類中的序號,來實例化具體的類。

?
1
2
3
4
5
6
7
8
9
10
11
switch(format.ordinal()) {
case 1:
  writer = new AztecWriter();
  break;
case 2:
  writer = new CodaBarWriter();
  break;
case 3:
  writer = new Code39Writer();
  break;
...............

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

?
1
2
3
4
5
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 動態實例化類的一段方法代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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 ,效率無疑是最高的。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美一级视频在线高清观看 | 99久久一香蕉国产线看观看 | 欧美一级精品 | 久久水蜜桃亚洲AV无码精品偷窥 | 天天av天天翘天天综合网 | 男同互操 | 韩国日本在线观看 | 调教女高中生第3部分 | 欧美a级在线观看 | 色偷偷91久久综合噜噜噜 | 性伴交换多p| 国产农村一级特黄α真人毛片 | 91国语精品自产拍在线观看一 | 毛片在线看网站 | 五月最新商场女厕所高跟嘘嘘 | 色天天久久 | 精品久久久噜噜噜久久久app | 日本一区视频 | 女人张开腿 让男人桶个爽 免费观看 | 国产成人在线免费视频 | 久久99亚洲热最新地址获取 | 91在线视频导航 | 99视频一区 | 纲手被漫画aⅴ | 40分钟在线观看免费 | 国产酒店自拍 | 国产精品久久久免费视频 | 王淑兰与铁柱全文免费阅读 | 成年人免费在线视频 | 国产精品国色综合久久 | 久久综合中文字幕佐佐木希 | 四虎国产成人免费观看 | 四虎影视4hu最新地址在线884 | 楚乔传第二部免费观看全集完整版 | 亚洲黄视频在线观看 | 91香蕉国产在线观看人员 | 午夜A级理论片左线播放 | 欧美日韩精 | 日韩精品福利视频一区二区三区 | 欧美一级片免费在线观看 | 扒开双腿疯狂进出爽爽动态图 |