関数ポインタをJava
-
21-08-2019 - |
質問
こんな複雑なプロセスにつかえることは困コンクリートの答えです。クライアントまで、フルのC#がコンセプトの代表者に要するエネルギーへの取り組みを強化していうの機能のポインタからC++.いは類似の機能をJava?このポインタがやや欠席には、どうするのがベストなのか。とを明らかにし、しかし最初のクラスです。
解決
Javaムのための関数ポインタ-ような機能は匿名クラスの実施はインターフェースなど
Collections.sort(list, new Comparator<MyClass>(){
public int compare(MyClass a, MyClass b)
{
// compare objects
}
});
更新: 上記の必要なJavaのバージョン以前のJava8.い素晴らしい選択肢、すなわちlambdas:
list.sort((a, b) -> a.isGreaterThan(b));
方法参考文献:
list.sort(MyClass::isGreaterThan);
他のヒント
あなたは、インターフェイスを持つ関数ポインタをsubstitueすることができます。あなたがコレクションを実行したいと言うと、各要素に何かをすることができます。
public interface IFunction {
public void execute(Object o);
}
これは、我々はいくつかに渡すことができるインタフェースがCollectionUtils2.doFunc(コレクション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でファーストクラスのオブジェクトではありません。あなたは、ハンドラクラスを実装することで同じことを行うことができます - これは、コールバックがスイングなどに実装されている方法です。
。がありますが、クロージャの提案のJavaの将来のバージョンでは(あなたが何を言ってるのかの正式名称) - <のhref = "http://www.javaworld.com/javaworld/jw-06-2008/ JW-06-closures.html」のrel = "noreferrerは"> Javaworld のは興味深い記事があります。
このはでスティーブ・イェジの実行を思い起こさせます名詞の王国。それは基本的に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
}
}
Javaではそのような事はありません。あなたは、いくつかのオブジェクトに、あなたの関数をラップし、そのオブジェクトのメソッドへの参照を渡すために、そのオブジェクトへの参照を渡す必要があります。
文法的に、これはインプレース定義された匿名クラスまたはクラスのメンバ変数として定義され、匿名のクラスを使用することによって、ある程度緩和することができます。
例:
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");
}
}
}
いてコールバック/delegate支援Javaを使用している。詳細に努源 ご自分のサイト.
その作品
しい原理という名前のクラスのコールバックを入れ子のクラス名WithParms.APIのニーズにコールバック、コールバック関数オブジェクトとしてパラメータが必要です。をコールバック.WithParms方法としては可変となります。以来、多くのアプリケーションのこのオブジェクトが再帰的に、この作品は非常に削除する
性能も高い優先したいと考えていないことが必要となる使い捨てオブジェクトの配列を保持するパラメータを呼び出しごと-すべての大規模なデータ構造ができる何千人もの素子、およびメッセージの処理のシナリオとしてプレーの確認はできて処理数千人のデータ構造です。
するためのthreadsafeのパラメータの配列のニーズに存在する独特の各メソッドの呼び出しAPI方法、効率的に使うべきなの各メソッドの呼び出しのコールバック;その第二のオブジェクトを安く作るために結合するコールバックをパラメータ配列を呼び出し.でも、シナリオを呼び出し側が既にパラメータの配列。これら二つの理由は、パラメータの配列をこのコールバック関数オブジェクトです。また、選択肢のメソッド呼び出し(通のパラメータとして配列または個々のオブジェクト)の組織に所属し、手のAPIをコールバックとなったことによるものであり使用のいずれかの呼び出しに最適での内部に点在している。
のWithParms入れ子のクラスはオプションとして二つの目的が含まれますが、パラメータオブジェクトの配列をコールバックメソッドの呼び出しで、10過負荷を呼び出す()メソッド(1~10パラメータ)を負荷パラメータ配列を呼び出してコールバックす。
彼らはlambdajライブラリに実装されているかクロージャを確認してください。彼らは実際にはC#の代表者と非常に類似した挙動を持っています:
ほとんどの人への相対は、ここで私は、Javaに新しいですが、私は同様の提案を見ていないので、私が提案する別の代替を持っています。イムわからないが、その場合は良い練習かどうかは、あるいは前に提案し、私はちょうどそれを取得できませんでした。私はその自己記述的だと思うので、私はそれが好きです。
/*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;
次に、用途に応じて、割り当てる
functionpointer = new Function1();
functionpointer = new Function2();
など。
と
で呼び出します functionpointer.execute();