2013-02-24 76 views
6

Có cách nào để ràng buộc các tham số tham số với các con trỏ hàm trong Java như bạn có thể với std :: bind trong C++ không? Java tương đương với cái gì như thế này?Tương đương với std :: C++ trong C++ của C++?

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; 
} 

Trả lời

2

Đây là càng gần như tôi nghĩ rằng bạn có thể nhận được một dòng theo bản dịch dòng, bind không ánh xạ 1: 1 cho bất kỳ cấu trúc Java nào;

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"); 
    } 
} 
+0

+1: Vâng, tốt hơn tôi – Aubin

0

Bạn có thể tạo một lớp ẩn danh có chức năng chữ ký mong muốn, chuyển tiếp cuộc gọi đến chức năng gốc.

Hãy nói rằng bạn có các chức năng:

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); 
    } 
} 

Sau đó, bạn có thể tạo các lớp học vô danh mà hiệu quả ràng buộc đối số cho các chức năng này.

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"); 
    } 
} 
+0

Quá nhiều 'mới' cho tôi, hai phương pháp StringPrinter có thể tĩnh – Aubin

+0

Trong trường hợp này đó là những chỉ là một ví dụ về những gì bạn có thể muốn ràng buộc * đến*. Nói chung, thích các phương thức ví dụ để tĩnh tốt hơn hỗ trợ khả năng thừa kế và tiêm sau này. –

2

Tôi sợ không, nhưng mã này là một cách tiếp cận để bắt chướC++ mẫu C (kém):

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"); 
     } 
    } 
} 

Đầu ra:

foo, 4 
foo, bar 
1

Từ Java7 trên, người ta có thể làm điều tương tự cũng có tay cầm phương pháp, xem doc API của lớp java.lang.invoke.MethodHandle để biết chi tiết.

0

Sử dụng MethodHandle, đây là một ví dụ

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(); 
    } 

} 
Các vấn đề liên quan