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 provides a set of common functional interfaces. whereas you could do the following:
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
}
}
There is no such thing in Java. You will need to wrap your function into some object and pass the reference to that object in order to pass the reference to the method on that object.
Syntactically, this can be eased to a certain extent by using anonymous classes defined in-place or anonymous classes defined as member variables of the class.
Example:
class MyComponent extends JPanel {
private JButton button;
public MyComponent() {
button = new JButton("click me");
button.addActionListener(buttonAction);
add(button);
}
private ActionListener buttonAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
// handle the event...
// note how the handler instance can access
// members of the surrounding class
button.setText("you clicked me");
}
}
}
I have implemented callback/delegate support in Java using reflection. Details and working source are available on my website.
How It Works
We have a principle class named Callback with a nested class named WithParms. The API which needs the callback will take a Callback object as a parameter and, if neccessary, create a Callback.WithParms as a method variable. Since a great many of the applications of this object will be recursive, this works very cleanly.
With performance still a high priority to me, I didn't want to be required to create a throwaway object array to hold the parameters for every invocation - after all in a large data structure there could be thousands of elements, and in a message processing scenario we could end up processing thousands of data structures a second.
In order to be threadsafe the parameter array needs to exist uniquely for each invocation of the API method, and for efficiency the same one should be used for every invocation of the callback; I needed a second object which would be cheap to create in order to bind the callback with a parameter array for invocation. But, in some scenarios, the invoker would already have a the parameter array for other reasons. For these two reasons, the parameter array did not belong in the Callback object. Also the choice of invocation (passing the parameters as an array or as individual objects) belongs in the hands of the API using the callback enabling it to use whichever invocation is best suited to it's inner workings.
The WithParms nested class, then, is optional and serves two purposes, it contains the parameter object array needed for the callback invocations, and it provides 10 overloaded invoke() methods (with from 1 to 10 parameters) which load the parameter array and then invoke the callback target.
Check the closures how they have been implemented in the lambdaj library. They actually have a behavior very similar to C# delegates:
http://code.google.com/p/lambdaj/wiki/Closures
Relative to most people here I am new to java but since I haven't seen a similar suggestion I have another alternative to suggest. Im not sure if its a good practice or not, or even suggested before and I just didn't get it. I just like it since I think its self descriptive.
/*Just to merge functions in a common name*/
public class CustomFunction{
public CustomFunction(){}
}
/*Actual functions*/
public class Function1 extends CustomFunction{
public Function1(){}
public void execute(){...something here...}
}
public class Function2 extends CustomFunction{
public Function2(){}
public void execute(){...something here...}
}
.....
/*in Main class*/
CustomFunction functionpointer = null;
then depending on the application, assign
functionpointer = new Function1();
functionpointer = new Function2();
etc.
and call by
functionpointer.execute();
참고URL : https://stackoverflow.com/questions/1073358/function-pointers-in-java
'development' 카테고리의 다른 글
파이썬에 레이블 / 고토가 있습니까? (0) | 2020.06.14 |
---|---|
특정 파일을 무시하는 대신 특정 파일 만 포함하도록 git에 지시하는 방법이 있습니까? (0) | 2020.06.14 |
jQuery로 텍스트 색상을 어떻게 변경할 수 있습니까? (0) | 2020.06.14 |
pandoc을 사용하여 Markdown에서 PDF로 변환 할 때 여백 크기 설정 (0) | 2020.06.14 |
유래 (0) | 2020.06.14 |