7

C++のstd::bindでできるように、Javaでパラメーターパラメーターを関数ポインターにバインドする方法はありますか?このようなものに相当するJavaは何でしょうか?

void PrintStringInt(const char * s, int n)
{
    std::cout << s << ", " << n << std::endl;
}

void PrintStringString(const char * s, const char * s2)
{
    std::cout << s << ", " << s2 << std::endl;
}

int main()
{
    std::vector<std::function<void(const char *)>> funcs;
    funcs.push_back(std::bind(&PrintStringInt, std::placeholders::_1, 4));
    funcs.push_back(std::bind(&PrintStringString, std::placeholders::_1, "bar"));
    for(auto i = funcs.begin(); i != funcs.end(); ++i){
        (*i)("foo");
    }
    return 0;
}
4

5 に答える 5

2

これは、行ごとの変換に到達できると私が思う限り近いものであり、bindJava構造に1:1でマップすることはありません。

static void PrintStringInt(String s, int n)
{
    System.out.println(s + ", " + n);
}

static void PrintStringString(String s, String s2)
{
    System.out.println(s + ", " + s2);
}

interface MyCall {
    void fn(String value);
}

public static void main(String[] argv)
{
    Vector<MyCall> funcs = new Vector<MyCall>();
    funcs.add(new MyCall() { 
      @Override public void fn(String value) {PrintStringInt(value, 4); }});
    funcs.add(new MyCall() { 
      @Override public void fn(String value) {PrintStringString(value, "bar"); }});
    for(MyCall i : funcs){
        i.fn("foo");
    }
}
于 2013-02-24T15:33:48.710 に答える
2

残念ながらそうではありませんが、このコードは C++ テンプレートを (不十分に) 模倣するためのアプローチです。

abstract class Printer<T> {
   final T value;
   Printer( T v ) {
      value = v;
   }
   public abstract void print( String s );
}

class PrintStringInt extends Printer< Integer> {
   PrintStringInt( int v ) {
      super( v );
   }
   @Override public void print( String s ) {
      System.out.printf( "%s, %d\n", s, value );
   }
}

class PrintStringString extends Printer< String > {
   PrintStringString( String v ) {
      super( v );
   }
   @Override public void print( String s ) {
      System.out.printf( "%s, %s\n", s, value );
   }
}

public class BindTest {
   public static void main( String[] args ) {
      Printer<?>[] funcs = {
         new PrintStringInt( 4 ),
         new PrintStringString( "bar")
      };
      for( Printer<?> p : funcs ) {
          p.print( "foo" );
      }
   }
}

出力:

foo, 4
foo, bar
于 2013-02-24T15:28:11.727 に答える
1

Java7 以降では、メソッド ハンドルでも同じことができます。詳細については、クラスの API ドキュメントをjava.lang.invoke.MethodHandle参照してください。

于 2013-02-24T17:57:14.770 に答える
1

MethodHandle を使用します。例を次に示します。

public class HW
{
    int sum;

  public HW(int a, int b)
  {
    super();
    this.sum = a+b;
  }


  public void hello1(double c)
  {
    double newnumber = sum+c;
   System.out.println("hello from hello1, new number= " + newnumber);
  }

  public void hello2()
  {        
   System.out.println("hello from hello2, sum=" + sum);
  }
}

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;


public class TestMethodHandle
{

/**
 * @param args
 */
  public static void main(String[] args)
  {

    HW hw = new HW(10, 15);
    MethodHandles.Lookup lookup = MethodHandles.lookup();
    MethodHandle mh;
    try
    {
        mh = lookup.findVirtual(HW.class, "hello2",
                                             MethodType.methodType(void.class));
        mh.invoke(hw);

        mh = lookup.findVirtual(HW.class, "hello1",
                MethodType.methodType(void.class, double.class));
        mh.invoke(hw, 20);

    } catch (NoSuchMethodException e)
    {
        e.printStackTrace();
    } catch (IllegalAccessException e)
    {
        e.printStackTrace();
    } catch (Throwable e)
    {
        e.printStackTrace();
    }

}
于 2015-12-18T20:47:42.987 に答える
0

元の関数への呼び出しを転送する、目的の署名の関数を持つ匿名クラスを作成できます。

これらの機能があるとしましょう:

public class StringPrinter {
    public void printStringInt( String s, int n ) {
       System.out.println( s + ", " + n );
    }

    public void printStringString( String s, String s2 ) {
       System.out.println( s + ", " + s2 );
    }
}

次に、引数をこれらの関数に効果的にバインドする匿名クラスを作成できます。

public static void main( String[] args ) {
     public interface Print1String {
         public void printString( String s );
     }

     List<Print1String> funcs = new ArrayList<Print1String);
     funcs.add( new Print1String() {
        public void printString( String s ) {
            new StringPrinter( ).printStringInt( s, 42 ); 
        }});
     funcs.add( new Print1String() {
        public void printString( String s ) {
            new StringPrinter( ).printStringString( s, "bar" ); 
        }});

     for ( Print1String func : funcs ) {
         func.print1String("foo");
     }
}
于 2013-02-24T15:17:59.020 に答える