2016-10-09 4 views
1

배열의 인수 중에서 선택하고 특정 인수를 반환하는 메서드가 있습니다. 예를 들어, 여기에서 그 방법 :인수 전달을위한 메서드/함수를 포함하는 배열

private <T> T selectOnType(T[] selection, T defaultOp){ 
    switch(this.type){ 
     case Resources.TEXT: 
      return selection[Resources.TEXT]; 
     case Resources.LISTEN: 
      return selection[Resources.LISTEN]; 
     default: 
      return defaultOp; 
    } 
} 

방법 I이 방법에 대한 참조 (즉, 함수 포인터)이 상기 방법으로 그 배열을 전달할 수있게하기 위하여 전체 어레이를 구성 할 수 있는가?

나는 같은 일을 시도 :

java.util.function.Function<Void, Void>[] array = {ClassA::method1, ClassA::method2}; 

(방법 항목 및 방법 항목은 인수를 수행하지 않고 무효 반환 곳)

을하지만 그 말 컴파일러 오류가 발생합니다 :

호환되지 않는 형식 : 잘못된 메서드 참조이지만 인수가 필요하지 않습니다.        
결과 :
        이유를 java.lang.Void : 실제와 형식 인수 목록의 길이가 다른

나는 같은 람다 놀아되었습니다

() -> ClassA.method1() 

그러나 나는 그것을 작동시킬 수 없었다. 누구든지 내가 뭘 잘못하고이 문제에 대한 해결책을 알고 있습니까?

편집 : 내가 스택 오버플로this를 봐 왔지만,이 C#을위한 것이며 내가 자바를 모방하는 방법을 알아 내지 못했다.

예 :

public class Word{ 
    private final String text; 
    private int listenCorrect = 0, textCorrect = 0; 
    public Word(final String test){ 
     this.text = text; 
    } 
    public void incListenCorrect(){ 
     listenCorrect++; 
    } 
    public void incTextCorrect(){ 
     textCorrect--; 
    } 
} 

을 마지막으로 나는 Main 클래스가 :
은 이제 나는 Word 클래스가 있다고 가정 해 봅시다.

public class Main{ 
    int type = 0; 
    public void action(){ 
     Word word = new Word("Hello"); 
     // 'Functions' is used to represent something I tried above (just for demonstration) 
     Function[] array = {word::incListenCorrect, word::incTextCorrect}; 
     Function picked = selectOnType(array, word::incTextCorrect); 
     picked.call(); 
    } 
    /* 
    * Resources is another class that contains the following values: 
    *   public static final int TEXT  = 0; 
    *   public static final int LISTEN  = 1; 
    */ 
    private <T> T selectOnType(T[] selection, T defaultOp){ 
     switch(this.type){ 
      case Resources.TEXT: 
       return selection[Resources.TEXT]; 
      case Resources.LISTEN: 
       return selection[Resources.LISTEN]; 
      default: 
       return defaultOp; 
     } 
    } 
} 
+1

'method1'과'method2' 인스턴스 메소드 또는 정적 메소드입니까? – ajb

+0

당신의 메소드는'Function '과 같지 않습니다.'Runnable' – njzk2

+0

@ajb 제가 포함 된 예제를보십시오; 그것들은 인스턴스 메소드입니다. –

답변

3

Function : 나는 (아래 참조) type 중 하나 listen 또는 text 경우 그 사이에 선택하는 순서대로 이러한 두 가지 방법으로 배열을 갖고 싶어합니다 (Main 클래스)를 action 방법 내부 하나의 인수를 취하여 결과를 리턴하는 메소드입니다. 인수를 취하지 않고 결과를 반환하지 않는 메서드를 사용하고 있습니다. 이 경우 Function을 사용할 수 없습니다. (Void을 사용하면이 문제를 해결할 수 없습니다.) the java.util.function 패키지에는 다른 일반적인 조합에 대한 몇 가지 클래스가 있습니다 (인수를 취하지 않고 결과를 반환하는 메소드, 두 개의 인수를 가지며 결과를 반환하지 않습니다. 유형이 클래스 유형이 아니기 때문에 Function에서 작동하지 않는 기본 결과를 반환하거나 원시 인수를 사용하는 메소드).

는 인수없이 결과 기능 인터페이스에 대한 java.util.function의 클래스 가 아니라, Runnable는 사용할 수 있습니다.

올바른 인터페이스를 사용해야합니다.

참고 :이 인수, 인스턴스 메소드 걸릴 것으로도 숨겨진 "예"인수를하지 않도록 내가 method1method2을 가정했다가, 정적 메서드입니다. 그것들이 인스턴스 메소드라면, 상황을 다르게해야합니다.

이제는 인스턴스 메소드라는 것을 분명히 했으므로 상황은 다르지만 메소드를 얻는 방법에 따라 다릅니다.

Word::incListenCorrect 

당신이 클래스 이름을 사용하고 있기 때문에 인스턴스를 인수로 제공해야합니다. 따라서 Word::incListenCorrectConsumer<Word>과 같이 하나의 인수를 사용하는 메서드에 대한 함수 인터페이스를 반환하며 .accept() 메서드를 호출 할 때는 Word을 인수로 전달해야합니다. 그러나 :

word::incListenCorrect 

는 매우 다르다. 이제 word 인스턴스는 메서드 참조로 "baked"되므로 인수로 전달할 필요가 없습니다. 따라서이 경우에는 인수를 사용하지 않고 값을 반환하지 않는 인터페이스가 필요합니다 (Runnable). rRunnable입니다 당신이

Runnable r = word::incListenCorrect;  
r.run(); 

을 말할 때 word 당신이 그것에 방법 참조를 할당 할 때 r의 일부가 된 이후, 자동, 인스턴스 메소드의 인스턴스로 word을 사용합니다.

+0

이것 좀 보겠습니다. 또한 내가 추가 한 예를 살펴보고 내가하는 일 (예 : 정적 방법이 아님)을 더 명확히하기 위해 추가했습니다. –

+0

당신, 내 친구는 환상적입니다! :) "x"개의 인수를 취하여 결과를 반환하는 인스턴스 메서드 (위의 예제와 같이)가 있으면 람다를 사용하겠습니까? Run() 메소드가 인자를 가지지 않고 void 함수이기 때문에 더 이상'Runnable' 객체로 래핑 할 수 없다고 생각합니다. 그래서 그 안에 무엇을 넣을까요? –

+1

여기서 문제는'Runnable','Consumer ','Function '등 올바른 타입이 필요하다는 것입니다. 1 개 또는 2 개의 인수가있는 경우, java.util.function의 인터페이스의 1 개를 사용할 수 있습니다 (인수의 일부가 원시적 형이며, 다음에있을 수도 있고하지 않을 수도 있습니다). > = 3 인수가 있으면 자체 인터페이스 유형을 정의해야하며 메소드 참조를 사용할 수 있습니다. 람다 (lambda)는 여러분이 자신의 타입을 정의 할 필요성을 피하는 데 도움이되지 않습니다. – ajb