程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 詳解Java的回調機制

詳解Java的回調機制

編輯:關於JAVA

詳解Java的回調機制。本站提示廣大學習愛好者:(詳解Java的回調機制)文章只能為提供參考,不一定能成為您想要的結果。以下是詳解Java的回調機制正文


模塊之間老是存在這必定的接口,從挪用方法上看,可以分為三類:同步驟用、回折衷異步驟用。上面側重詳解回調機制。

1. 概述

Java 中的回調機制是一個比擬罕見的機制,只是有能夠在你的法式中應用得比擬少,在一些年夜型的框架中回調機制到處可見。本文就經由過程一些詳細的實例,漸漸走近 Java 的回調機制。

2.回調

所謂回調:就是A類中挪用B類中的某個辦法C,然後B類中反過去挪用A類中的辦法D,D這個辦法就叫回調辦法。現實在應用的時刻,也會有分歧的回調情勢,好比上面的這幾種。

2.1 同步回調

這裡我假定如許的一種情形。

A 公司的總監 B 跟他的部屬(項目司理 C)說要做一個調研,不外不消 C 本身親力親為。可讓司理 C 去支配他上面的法式員 D 去完成。司理 C 找到了法式員 D,並告知他,如今要完成一個調研義務。而且把調研的成果告知司理 C。假如有成績,照樣要持續的。 由於這裡是 C 讓 D 去做一件工作,以後 D 照樣要將成果與 C 停止溝通。如許就是回調的模子了。上面是普通回調的類圖:

起首我們要有一個回調的接口 CallbackInterface

CallbackInterface.java

public interface CallbackInterface {
  public boolean check(int result);
}

配景裡,法式員 D 是要將成果與項目司理 C 停止溝通的,所以這裡項目司理須要完成下面的回調接口:

Manager.java

public class Manager implements CallbackInterface {

  private Programmer programmer = null;

  public Manager(Programmer _programmer) {
    this.programmer = _programmer;
  }

  /**
   * 用於 Boss 下達的拜托
   */
  public void entrust() {
    arrange();
  }

  // 停止支配部屬停止 study 任務
  private void arrange() {
    System.out.println("Manager 正在為 Programmer 支配任務");
    programmer.study(Manager.this);
    System.out.println("為 Programmer 支配任務曾經完成,Manager 做其他的工作去了。");
  }

  @Override
  public boolean check(int result) {
    if (result == 5) {
      return true;
    }
    return false;
  }

}

關於法式員 D 來講他須要持有一個司理 C 的援用,以便與他溝通。不外,這裡是總監 B 讓 司理 C 去支配的義務。也就是說這裡也能夠讓其他的司理,好比說司理 B1, B2等等。由於司理都完成了回調的接口,所以這裡便可以直接讓法式員 D 持有這個接口便可以了。以下:

Programmer.java

public class Programmer {

  public void study(CallbackInterface callback) {
    int result = 0;
    do {
      result++;
      System.out.println("第 " + result + " 次研討的成果");
    } while (!callback.check(result));

    System.out.println("調研義務停止");
  }
}

關於總監來講就更簡略清楚明了了,由於這相當於一個 Client 測試:

Boss.java

public class Boss {

  public static void main(String[] args) {
    Manager manager = new Manager(new Programmer());
    manager.entrust();
  }
}

運轉成果:

Manager 正在為 Programmer 支配任務
第 1 次研討的成果
第 2 次研討的成果
第 3 次研討的成果
第 4 次研討的成果
第 5 次研討的成果
調研義務停止
為 Programmer 支配任務曾經完成,Manager 做其他的工作去了。

2.2 異步回調

照樣下面的例子,你的項目司理弗成能要一向等你調研的成果。而是把這個義務交給你以後,他就不論了,他做他的,你做你的。所以,這裡須要對回調的函數停止異步處置。
所以,這裡我們須要修正 Programmer 類的代碼,修正以下:

Programmer.java

public class Programmer {

  public Programmer() {
  }

  public void study(CallbackInterface callback) {
    new StudyThread(callback).start();
  }

  // --------------------------- Programmer 正在做的任務 ---------------------------

  class StudyThread extends Thread {

    CallbackInterface callback = null;

    public StudyThread(CallbackInterface _callback) {
      callback = _callback;
    }

    @Override
    public void run() {
      int result = 0;
      do {
        result++;
        System.out.println("第 " + result + " 次研討的成果");
      } while (!callback.check(result));

      System.out.println("調研義務停止");
    }
  }
}

運轉成果:

Manager 正在為 Programmer 支配任務
為 Programmer 支配任務曾經完成,Manager 做其他的工作去了。
第 1 次研討的成果
第 2 次研討的成果
第 3 次研討的成果
第 4 次研討的成果
第 5 次研討的成果
調研義務停止

2.3 閉包與回調

閉包(closure)是一個可挪用的對象,它記載了一些信息,這些信息來自於創立它的感化域。

2.3.1 通俗挪用

起首,我們可以看看在正常情形下的挪用是怎樣停止的。
Incrementable.java

interface Incrementable {
  void increment();
}

這是一個通俗的接口(在通俗挪用裡只是通俗接口,在回調中就是回調接口,這一點應當很好懂得吧)。

Callee1.java

class Callee1 implements Incrementable {

  private int i = 0;

  @Override
  public void increment() {
    i++;
    System.out.println(i);
  }

}

Callbacks.java

public class Callbacks {
  public static void main(String[] args) {
    Callee1 callee1 = new Callee1();
    callee1.increment();
  }
}

Callbacks 是一個測試客戶端類,沒啥好說的,直接看下面的代碼。

2.3.2 回調初試

下面的通俗挪用也沒啥好說的,由於這關於一個正常的 Java 法式員來講都應當是想都不消想便可以弄定的工作。

如今假如要組成回調,那末關於法式的構造或是邏輯的思想上都弗成能只要一個被挪用者(被回調的對象 Callee1),還須要一個挪用者對象。挪用者可以像上面如許來編寫:

Caller.java

class Caller {

  private Incrementable callbackReference;

  public Caller(Incrementable _callbackReference) {
    callbackReference = _callbackReference;
  }

  void go() {
    callbackReference.increment();
  }
}

這裡 Caller 持有一個回調接口的援用 callbackReference,就像在下面說到的法式員須要持有一個項目司理的援用,如許便可以經由過程這個援用來與項目司理溝通。這裡的 callbackReference 也恰是起到了這個感化。

如今我們來看看測試類的編寫:

Callbacks.java

public class Callbacks {
  public static void main(String[] args) {
    Callee1 callee1 = new Callee1();    
    Caller caller1 = new Caller(callee1);
    caller1.go();
  }
}

關於到今朝為止的法式代碼,完整可以比較下面項目司理支配法式員調研技巧困難的代碼。有異曲同工之妙。

2.3.3 閉包回調

比擬於正常的回調,閉包回調的焦點天然是在於閉包,也就是對感化域的掌握。
如今假定有一個用戶(其他法式員)自界說了一個 MyInCrement 類,同時包括了一個 increment 的辦法。以下:

class MyInCrement {

  public void increment() {
    System.out.println("MyCrement.increment");
  }

  static void f(MyInCrement increment) {
    increment.increment();
  }
}

別的有一個類 Callee2 繼續自下面這個類:

class Callee2 extends MyInCrement {

  private int i = 0;

  public void increment() {
    super.increment();
    i++;
    System.out.println(i);
  }
}

不言而喻這裡假如要挪用 increment() 辦法,就釀成了普通的函數挪用了。所以這裡我們須要修正下面的 Callee2 類,修正的目的就是讓 Callee2 類可以兼容 MyInCrement 類的 increment() 辦法和 Incrementable 的 increment() 辦法。修正後:

class Callee2 extends MyInCrement {

  private int i = 0;

  public void increment() {
    super.increment();
    i++;
    System.out.println(i);
  }

  private class Closure implements Incrementable {

    @Override
    public void increment() {
      Callee2.this.increment();
    }
  }

  Incrementable getCallbackReference() {
    return new Closure();
  }
}

留意,這裡的 Closure 類是一個公有的類,這是一個閉包的要素。由於 Closure 類是公有的,那末就要有一個對外開放的接口,用來對 Closure 對象的操作,這裡就是下面的 getCallbackReference() 辦法。 Caller 類則沒有轉變。
關於測試客戶端就直接看代碼吧:

public class Callbacks {
  public static void main(String[] args) {    
    Callee2 callee2 = new Callee2();
    Caller caller2 = new Caller(callee2.getCallbackReference());
    caller2.go();
  }
}

以上就是本文的全體內容,願望對年夜家的進修有所贊助,也願望年夜家多多支撐。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved