2011-11-21 23 views
10

Hãy kiểm tra sau:Tôi có thể buộc phải định hướng các phương pháp quá tải được gọi là tê giác không?

public static class Scripted { 
    public void setThing(List<?> list) { 
     System.out.println("Set via list"); 
    } 

    public void setThing(Object[] array) { 
     System.out.println("Set array"); 
    } 
} 

@Test 
public void testScripting() throws Exception { 
    ScriptEngine engine = new ScriptEngineManager().getEngineByExtension("js"); 
    engine.getContext().setAttribute("s", new Scripted(), ScriptContext.ENGINE_SCOPE); 
    engine.eval("s.thing = Array(1, 2, 3);"); 
} 

Với phiên bản của tê giác vận chuyển với Java 7, nếu bạn chạy này, bạn sẽ nhận được một ngoại lệ như thế này:

javax.script.ScriptException: sun.org.mozilla.javascript.internal.EvaluatorException: The choice of Java constructor setThing matching JavaScript argument types (object) is ambiguous; candidate constructors are: 
    void setThing(java.util.List) 
    void setThing(java.lang.Object[]) (<Unknown source>#1) in <Unknown source> at line number 1 

Các Object[] tình trạng quá tải hiện hữu trong đầu tiên là vì phiên bản trước của tê giác sẽ không tự động chuyển đổi mảng thành List, nhưng nó sẽ chuyển đổi chúng thành Object[].

Nếu đây là dự án cá nhân, đây là nơi tôi sẽ chỉ xóa quá tải Object[]. Vấn đề là đây là một API công cộng và có thể có ai đó đang gọi phương thức đó ngay bây giờ. Tôi vẫn muốn nâng cấp lên Java 7 nhưng tôi muốn tránh làm phiền người dùng JavaScript hoặc những người sử dụng phiên bản mảng của phương thức.

Có cách nào để ẩn các phương thức bị quá tải Object[] từ Tê giác trong khi những người khác vẫn có thể gọi chúng?

Trả lời

10

Mặc dù nó không phải là rất thanh lịch có một cách cụ thể gọi một phương thức Java quá tải. Nó được định nghĩa trong phần cuối cùng của thông số Java Method Overloading and LiveConnect 3. Về cơ bản, bạn sử dụng toàn bộ chữ ký của phương thức bạn muốn gọi khi nó được hiển thị trong thông báo lỗi, sử dụng ký hiệu dấu ngoặc vuông. Trong trường hợp của bạn, những điều sau đây sẽ hoạt động:

s["setThing(java.util.List)"](Array(1, 2, 3)); 

Thật không may là thay đổi chúng tôi đã thực hiện với mảng JavaScript triển khai java.util.List ngắt mã hiện có. Có lẽ nó sẽ là tốt hơn để chỉ cần chọn một trong trường hợp có nhiều phương pháp phù hợp.

+0

Tôi đồng ý ... nó sẽ tốt hơn nếu nó chỉ được gọi là Danh sách một mà không có thất bại như thế này. Nhưng Java 7 đã phá vỡ khá nhiều thứ khác trong ứng dụng của chúng tôi, đây chỉ là một trong số rất nhiều thứ (những thứ khác, như những thay đổi của Locale, đều được giải quyết.) – Trejkaz

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