欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java 的雙重分發(fā)與 Visitor 模式實例詳解

 更新時間:2018年07月08日 10:02:45   作者:侯樹成  
這篇文章主要介紹了Java 的雙重分發(fā)與 Visitor 模式實例詳解,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下

雙重分發(fā)(Double Dispatch)

什么是雙重分發(fā)?

談起面向對象的程序設計時,常說起的面向對象的「多態(tài)」,其中關于多態(tài),經常有一個說法是「父類引用指向子類對象」。

這種父類的引用指向子類對象的寫法類似下面這種:

Animal animal = new Dog(); 
animal.bark(); 

另一種常用的形式是

 public class Keeper { 
  public void say(Animal a) { 
   System.out.println("Animal say"); 
  } 
  public void say(Dog dog) { 
   System.out.println("dog say"); 
  } 
} 
Animal animal = new Animal(); 
Animal dog = new Dog(); 
Keeper keeper = new Keeper(); 
keeper.say(animal); 
keep.say(dog); 

那上面的keeper調用兩次say的時候,會輸出什么內容呢?會調用到兩個不同的方法嗎?

實際上在這兩次調用的時候,都會調用到say(Animal a)這個方法。由于這些內容在編譯期就能確實下來,這就是 Java 的 靜態(tài)分發(fā)。

 

從上面的圖我們看到,對于兩次調用生成的字節(jié)碼,確實都指向了say(Animal a)這個方法,運行時直接執(zhí)行方法,輸出了對應的內容。

那對應的animal.bark() 為什么最終會調用到 dog 類的方法?這是在運行時確定具體的方法接收者的類型并執(zhí)行。這就是所謂的動態(tài)分發(fā),在運行時確定具體的方法,實現(xiàn)面向對象的多態(tài)。

分發(fā)(Dispatch)

分發(fā)就是指最終確定一個要執(zhí)行的方法的過程。

對于 Java 等靜態(tài)語言來說,都是通過 單一分發(fā)(Single Dispatch)來進行的方法執(zhí)行。
比如這樣一行代碼

dog.eat(new Bone())

最終執(zhí)行要選擇的eat方法,只會根據(jù)dog的具體類型選擇到對應的方法,而傳入的參數(shù)并不能影響到對應方法的選擇,這種就是 single Dispatch

為了讓傳入的真實參數(shù),這里就是Bone來真正起到作用,就需要用到Double Dispatch或者叫做Multiple Dispatch

也就是說最終決定調用方法是哪一個的,不僅僅是方法的接收者,還受參數(shù)類型的決定。

Visitor 模式

在GoF 的設計模式中,Visitor 模式就使用到了Double Dispatch 達到了調用真實對象的目的。

對于Visitor 模式,最常用的例子是樹的遍歷。比如在處理到節(jié)點和樹葉時的方式有區(qū)別,此歸通過 visitor 的雙重分發(fā),實現(xiàn)對于不同的 Element ,執(zhí)行不同的內容。

代碼類似這樣:

node.accept(new ConcreateVisitor()); 
leaf.accept(new ConcreateVisitor()); 

node 中的 accept方法,會將自己的真實類型再次傳遞回visitor

public void accept(Visitor v) { 
 v.visit(this); 
} 

此時,在visitor中,就能根據(jù)真實的類型來調用具體的方法,對應node 和 leaf 分別有類似這樣的方法:

public void visit(Node n); 
public void visit(Leaf l); 

Visitor 總結起來一般是包含 visitor 接口,在visitor 接口中,包含各個即將被訪問的 Element對象的處理邏輯。在 各個Element 的具體實現(xiàn)中,再將自己的類型傳遞回visitor 進行二次分發(fā),實現(xiàn)確切邏輯的調用。
在Tomcat中的應用

Visitor 在Tomcat中也有應用,典型的是解析EL表達式。

比如org.apache.el.parser.Node

這個類中包含一個accept(NodeVisitor visitor)方法

實際的 Node 類型有很多,但在真實調用的這個時候,會通過

public void accept(NodeVisitor visitor) throws Exception { 
  visitor.visit(this); 

將真實類型傳回visitor, vistor中會調用具體的方法,從而實現(xiàn)參數(shù)也能起到決定作用的功能。

public void visit(Node node) throws ELException { 
  if (node instanceof AstFunction) { 
   AstFunction funcNode = (AstFunction) node; 
   Method m = null; 
 
   } else if (xxx) { 
 }

這里一般會聲明多個visit方法,然后上面的visit(this)會直接定位到目標方法上。
以上就是 Java 中的各類分發(fā),以及 visitor這種模式通過模式的形式來實現(xiàn)雙重分發(fā)的效果。希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復大家的!

相關文章

  • Jenkins安裝多個jdk版本并在項目中選擇對應jdk版本

    Jenkins安裝多個jdk版本并在項目中選擇對應jdk版本

    在使用jenkins構建項目時會遇到不同的job需要配置不同版本的jdk,下面這篇文章主要給大家介紹了關于Jenkins安裝多個jdk版本并在項目中選擇對應jdk版本的相關資料,需要的朋友可以參考下
    2024-03-03
  • 詳解java中finalize的實現(xiàn)與相應的執(zhí)行過程

    詳解java中finalize的實現(xiàn)與相應的執(zhí)行過程

    在常規(guī)的java書籍中,即會描述 object的finalize方法是用于一些特殊的對象在回收之前再做一些掃尾的工作,但是并沒有說明此是如何實現(xiàn)的.本篇從java的角度(不涉及jvm以及c++),有需要的朋友們可以參考借鑒。
    2016-09-09
  • idea創(chuàng)建包含多個springboot module的maven project的方法

    idea創(chuàng)建包含多個springboot module的maven project的方法

    這篇文章主要介紹了idea創(chuàng)建包含多個springboot module的maven project的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • Java基礎知識精通數(shù)組的使用

    Java基礎知識精通數(shù)組的使用

    數(shù)組對于每一門編程語言來說都是重要的數(shù)據(jù)結構之一,當然不同語言對數(shù)組的實現(xiàn)及處理也不盡相同。Java?語言中提供的數(shù)組是用來存儲固定大小的同類型元素
    2022-04-04
  • 深入解析java中的值傳遞和引用傳遞

    深入解析java中的值傳遞和引用傳遞

    這篇文章主要介紹了深入解析java中的值傳遞和引用傳遞,值傳遞是將變量的值復制給另一個變量,兩個變量之間并沒有直接關系,引用傳遞是將變量的引用(內存地址)傳遞給另一個變量,兩個變量之間指向同一個內存地址,修改一個變量的值也會影響到另一個變量
    2023-07-07
  • 解決idea啟動報錯javax.imageio.IIOException的問題

    解決idea啟動報錯javax.imageio.IIOException的問題

    這篇文章主要介紹了idea啟動報錯javax.imageio.IIOException,解決打不開idea問題,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • SpringBoot生成PDF的五種實現(xiàn)方法總結

    SpringBoot生成PDF的五種實現(xiàn)方法總結

    這篇文章主要介紹了SpringBoot生成PDF的五種實現(xiàn)方法,在開發(fā)中經常會遇到需要進行對一些數(shù)據(jù)進行動態(tài)導出PDF文件,然后讓用戶自己選擇是否需要打印出來,這篇文章我們來介紹五種實現(xiàn)方法,需要的朋友可以參考下
    2024-10-10
  • Spring技巧之如何動態(tài)讀取配置文件

    Spring技巧之如何動態(tài)讀取配置文件

    這篇文章主要介紹了Spring技巧之如何動態(tài)讀取配置文件的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • SpringBoot集成P6Spy實現(xiàn)SQL日志的記錄詳解

    SpringBoot集成P6Spy實現(xiàn)SQL日志的記錄詳解

    P6Spy是一個框架,它可以無縫地攔截和記錄數(shù)據(jù)庫活動,而無需更改現(xiàn)有應用程序的代碼。一般我們使用的比較多的是使用p6spy打印我們最后執(zhí)行的sql語句
    2022-11-11
  • Spring boot 添加jsp支持配置詳解

    Spring boot 添加jsp支持配置詳解

    本篇文章主要介紹了Spring boot 添加jsp支持配置詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06

最新評論