[java] Java의 함수 포인터

이것은 일반적이고 사소한 것일 수 있지만 구체적인 답변을 찾는 데 어려움을 겪고있는 것 같습니다. C #에는 델리게이트의 개념이 있는데, 이는 C ++의 함수 포인터 개념과 밀접한 관련이 있습니다. Java에도 비슷한 기능이 있습니까? 포인터가 다소 없다는 것을 감안할 때 가장 좋은 방법은 무엇입니까? 그리고 분명히, 우리는 여기서 일등석으로 이야기하고 있습니다.



답변

함수 포인터와 같은 기능에 대한 Java 관용구는 인터페이스를 구현하는 익명 클래스입니다.

Collections.sort(list, new Comparator<MyClass>(){
    public int compare(MyClass a, MyClass b)
    {
        // compare objects
    }
});

업데이트 : 위는 Java 8 이전의 Java 버전에서 필요합니다. 이제 우리는 훨씬 더 좋은 대안, 즉 람다를 가지고 있습니다.

list.sort((a, b) -> a.isGreaterThan(b));

방법 참조 :

list.sort(MyClass::isGreaterThan);


답변

인터페이스로 함수 포인터를 대체 할 수 있습니다. 컬렉션을 살펴보고 각 요소로 무언가를 수행한다고 가정 해 봅시다.

public interface IFunction {
  public void execute(Object o);
}

이것은 우리가 CollectionUtils2.doFunc (Collection c, IFunction f)에 전달할 수있는 인터페이스입니다.

public static void doFunc(Collection c, IFunction f) {
   for (Object o : c) {
      f.execute(o);
   }
}

예를 들어 숫자 모음이 있고 모든 요소에 1을 추가하고 싶다고 가정하십시오.

CollectionUtils2.doFunc(List numbers, new IFunction() {
    public void execute(Object o) {
       Integer anInt = (Integer) o;
       anInt++;
    }
});


답변

반사를 사용하여 수행 할 수 있습니다.

객체와 메소드 이름을 문자열로 매개 변수로 전달한 다음 메소드를 호출하십시오. 예를 들면 다음과 같습니다.

Object methodCaller(Object theObject, String methodName) {
   return theObject.getClass().getMethod(methodName).invoke(theObject);
   // Catch the exceptions
}

그런 다음 다음과 같이 사용하십시오.

String theDescription = methodCaller(object1, "toString");
Class theClass = methodCaller(object2, "getClass");

물론 모든 예외를 확인하고 필요한 캐스트를 추가하십시오.


답변

아니요, 함수는 Java의 첫 번째 클래스 객체가 아닙니다. 핸들러 클래스를 구현하여 동일한 작업을 수행 할 수 있습니다. 이것은 Swing 등에서 콜백이 구현되는 방식입니다.

그러나 자바의 차기 버전에서는 클로저 (당신이 말하는 것에 대한 공식 이름)에 대한 제안이 있습니다 -Javaworld 는 흥미로운 기사를 가지고 있습니다.


답변

이것은 Steve Yegge의 명사에서처형 을 생각 나게한다 . 기본적으로 Java에는 모든 작업에 객체가 필요하므로 함수 포인터와 같은 “동사 전용”엔터티가 없습니다.


답변

비슷한 기능을 달성하기 위해 익명의 내부 클래스를 사용할 수 있습니다.

인터페이스를 정의하려는 경우 Foo:

interface Foo {
    Object myFunc(Object arg);
}

bar‘함수 포인터’를 인수로받을 메소드 를 작성하십시오 .

public void bar(Foo foo) {
    // .....
    Object object = foo.myFunc(argValue);
    // .....
}

마지막으로 다음과 같이 메소드를 호출하십시오.

bar(new Foo() {
    public Object myFunc(Object arg) {
        // Function code.
    }
}


답변

Java8은 람다 및 메소드 참조를 도입했습니다 . 따라서 함수가 기능 인터페이스 와 일치하면 (자신의 인터페이스 를 만들 수 있음)이 경우 메서드 참조를 사용할 수 있습니다.

Java는 공통 기능 인터페이스 세트를 제공합니다 . 반면 다음을 수행 할 수 있습니다.

public class Test {
   public void test1(Integer i) {}
   public void test2(Integer i) {}
   public void consumer(Consumer<Integer> a) {
     a.accept(10);
   }
   public void provideConsumer() {
     consumer(this::test1);   // method reference
     consumer(x -> test2(x)); // lambda
   }
}