프로그래밍 언어로:무엇을 가장 우아한 방법을 정의 콜백에서 Java?

StackOverflow https://stackoverflow.com/questions/813013

  •  03-07-2019
  •  | 
  •  

문제

이 책에서'코드를 완료하는'저자에 대해 이야기한 프로그래밍 언어(대신 프로그래밍 언어에서).그 뜻은,당신이하지 않아야에 자신을 제한으로 제한의 선택된 프로그래밍 언어입니다.

콜백은 자주 사용되는 기능입니다.내가 관심있:무엇을 가장 우아한 방법으로 프로그램을 콜백으로 java 언어?

도움이 되었습니까?

해결책

이 기사를 확인하십시오.

http://www.onjava.com/pub/a/onjava/2003/05/21/delegates.html

콜백은 본질적으로 특별한 경우 OD 대의원이며 (C#의대로),이 기사는 Java에서 C# Delegate와 유사한 것을 구현합니다.

다른 팁

Java는 모든 종류의 상황에 모든 종류의 콜백을 사용합니다. AWT 청취자의 가장 오래된 시절부터 Java는 콜백에 관한 것입니다.

Java 콜백에는 두 가지 기본 "맛"이 있습니다. 첫 번째는 구현 인터페이스 방법입니다.

public class MyThing implements StateChangeListener {

   //this method is declared in StateChangeListener
   public void stateChanged() {
      System.out.println("Callback called!");
   }

   public MyThing() {
      //Here we declare ourselves as a listener, which will eventually
      //lead to the stateChanged method being called.
      SomeLibraryICareAbout.addListener(this);
   }
}

Java 콜백의 두 번째 맛은 익명의 내부 클래스입니다.

public class MyThing {

   public MyThing() {
      //Here we declare ourselves as a listener, which will eventually
      //lead to the stateChanged method being called.
      SomeLibraryICareAbout.addListener( new StateChangeListener() {
          //this method is declared in StateChangeListener
          public void stateChanged() {
              System.out.println("Callback called!");
          }
      });
   }
}

반사 사용, 별도의 이벤트 처리 클래스 사용 및 어댑터 패턴을 포함한 다른 방법도 있습니다.

Java의 기능 포인터/대표가없는 상태에서 내가 본 가장 일반적인 방법은 기능을 사용하는 것입니다.

기본적으로 단일 메소드가있는 인터페이스를 정의하고 인스턴스를 콜백으로 사용하십시오.

public interface Callback<T,V>{
  public T invoke(V context);
}

C/C ++ 또는 C# 등가보다 더 많은 장점이지만 작동하지만 작동합니다. 표준 라이브러리 에서이 패턴의 예는 비교기 인터페이스입니다.

불행히도 Java에서는 기능이 일류 객체가 아닙니다. 당신이 할 수있는 최선은 인터페이스를 사용하는 것입니다.

public interface MyCallback
{
    public void theCallback(int arg);
}

public class Sample
{
    public static void takesACallback(MyCallback callback)
    {
        ...
        callback.theCallback(arg);
    }
}

public class Sample2
{
    public static void main(String[] args)
    {
        Sample.takesACallback(new MyCallback()
        {
            void theCallback(int arg)
            {
                // do a little dance
            }
        });
    }
}

매우 일반적인 Call Back Construction은 Swing의 이벤트 핸들러입니다. ActionListeners는 아마도 가장 간단합니다.

살펴보십시오 http://java.sun.com/docs/books/tutorial/uiswing/events/actionlistener.html

귀하는 종종 적절한 인터페이스를 구현하는 익명 클래스의 인스턴스를 제공합니다.

listener = new ActionListener() {
  public void actionPerformed(ActionEvent e) {
     // do stuff...
  }
};

그러면 듣는 사람에게 적절한 스윙 방법을 전달합니다.

나 개인적으로 자바 필사적으로 필요가 일부 형태의밈을 지원합니다.중간에,내가 구현한 반영이다-기초한 일반적 방법을 콜백에서 Java.그 에 게시된 내 웹사이트.

이 방식의 장점은 그것의 제네릭함.이 목표를 작성할 수 있 API 같이 파일 시스템을 걷는 트리없이 인터페이스를 정의하려면 각 시간에,대신 지정하는 방법에 코드를 사용하는 API 를 수행합니다.

예를 들어,걷는 파일 시스템을 프로세스는 각 파일:

프로세스는 디렉토리 트리 API

/**
 * Process a directory using callbacks.  To interrupt, the callback must throw an (unchecked) exception.
 * Subdirectories are processed only if the selector is null or selects the directories, and are done
 * after the files in any given directory.  When the callback is invoked for a directory, the file
 * argument is null;
 * <p>
 * The callback signature is:
 * <pre>    void callback(File dir, File ent);</pre>
 * <p>
 * @return          The number of files processed.
 */
static public int processDirectory(File dir, Callback cbk, FileSelector sel) {
    return _processDirectory(dir,new Callback.WithParms(cbk,2),sel);
    }

static private int _processDirectory(File dir, Callback.WithParms cbk, FileSelector sel) {
    int                                 cnt=0;

    if(!dir.isDirectory()) {
        if(sel==null || sel.accept(dir)) { cbk.invoke(dir.getParent(),dir); cnt++; }
        }
    else {
        cbk.invoke(dir,(Object[])null);

        File[] lst=(sel==null ? dir.listFiles() : dir.listFiles(sel));
        if(lst!=null) {
            for(int xa=0; xa<lst.length; xa++) {
                File ent=lst[xa];
                if(!ent.isDirectory()) {
                    cbk.invoke(dir,ent);
                    lst[xa]=null;
                    cnt++;
                    }
                }
            for(int xa=0; xa<lst.length; xa++) {
                File ent=lst[xa];
                if(ent!=null) { cnt+=_processDirectory(ent,cbk,sel); }
                }
            }
        }
    return cnt;
    }

프로세스를 사용하여 디렉토리 API

위의 방법이 기록된 바 내가 지금 아주 쉽게 공정한 디렉토리를 위해 모든 작업은;검사,계산,목록,등등.와 사소한 변경을 콜백을 호출에 디렉토리를 전후에 내림차순으로 작업에 다음과 같이 파일/트리 삭제 수행할 수도 있습(추가 매개 변수가 필요한을 나타내는 전/후의 자연 invocation).

static private final Method             COUNT =Callback.getMethod(Xxx.class,"callback_count",true,File.class,File.class);

...

IoUtil.processDirectory(root,new Callback(this,COUNT),selector);

...

private void callback_count(File dir, File fil) {
    if(fil!=null) {                                                             // file is null for processing a directory
        fileTotal++;
        if(fil.length()>fileSizeLimit) {
            throw new Abort("Failed","File size exceeds maximum of "+TextUtil.formatNumber(fileSizeLimit)+" bytes: "+fil);
            }
        }
    progress("Counting",dir,fileTotal);
    }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top