2009-11-23 45 views
16

Tôi khá mới đối với Java và tôi đang gặp phải sự cố phản ánh.Với Java phản ánh cách khởi tạo một đối tượng mới, sau đó gọi một phương thức trên đó?

Hãy nói rằng tôi phải tự động gọi phương thức fooMethod trên một thể hiện của lớp Foobar

tôi có cho đến nay một thể hiện của Foobar với:

Object instance = Class.forName("Foobar").newInstance(); 

Hãy nói rằng tôi biết có một phương pháp fooMethod trên đối tượng này (tôi thậm chí có thể kiểm tra điều này với Class.forName("Foobar").getDeclaredMethods()), làm thế nào để gọi nó, xin vui lòng?

Trả lời

2

này nên làm việc cho bạn:

((Foobar)instance).fooMethod() 
+1

bạn chỉ có thể làm điều đó nếu bạn biết tại thời gian biên dịch, ví dụ có nghĩa là sẽ có một Foobar - mà sau đó có nghĩa là bạn sẽ không cần phải sử dụng sự phản chiếu ngay từ đầu! – Chii

+2

@Chii: Không cần thiết. FooBar có thể là loại phổ biến nhất mà từ đó bạn nhận được thông qua sự phản chiếu. Đây là cách trình điều khiển JDBC ví dụ đang hoạt động và có bao nhiêu kiến ​​trúc plugin được thiết kế. – quosoo

6
Method method = getClass().getDeclaredMethod("methodName"); 
m.invoke(obj); 

Đây là trong trường hợp phương pháp này không có đối số. Nếu có, hãy thêm các kiểu đối số làm đối số cho phương thức này. obj là đối tượng bạn đang gọi phương thức.

See the java.lang.Class docs

+0

'getClass' là gì? –

3

Bạn có thể bắt đầu bằng cách đọc về nó here.

Đối với các mã bạn đang theo đuổi nó là như thế này (từ nguồn giống nhau):

Method[] allMethods = c.getDeclaredMethods(); 
    for (Method m : allMethods) { 
    String mname = m.getName(); 
    if (!mname.startsWith("test") 
     || (m.getGenericReturnType() != boolean.class)) { 
     continue; 
    } 
    Type[] pType = m.getGenericParameterTypes(); 
    if ((pType.length != 1) 
     || Locale.class.isAssignableFrom(pType[0].getClass())) { 
     continue; 
    } 

    out.format("invoking %s()%n", mname); 
    try { 
     m.setAccessible(true); 
     Object o = m.invoke(t, new Locale(args[1], args[2], args[3])); 
     out.format("%s() returned %b%n", mname, (Boolean) o); 

    // Handle any exceptions thrown by method to be invoked. 
    } catch (InvocationTargetException x) { 
     Throwable cause = x.getCause(); 
     err.format("invocation of %s failed: %s%n", 
       mname, cause.getMessage()); 
    } 
4

đơn thuần phản ánh: Method.invoke. Giải pháp khác là yêu cầu mục bạn đang tạo một cách phản chiếu để triển khai giao diện đã biết và truyền tới giao diện này và sử dụng như bình thường.

Loại thứ hai thường được sử dụng cho "plugin", trước đây không được sử dụng thường xuyên.

2

Bạn có thể sử dụng Reflection

lớp mẫu

package com.google.util; 
Class Maths 
{ 

public Integer doubleIt(Integer a) 
{ 
return a*2; 
} 
} 

và sử dụng giống như this-

bước 1: - Tải Class với tên đầu vào cho trước như String

Class<?> obj=Class.forName("Complete_ClassName_including_package"); 

//like:- Class obj=Class.forName("com.google.util.Maths"); 

bước 2: - có được phương pháp với tên được đặt và gõ thông số

Method method=obj.getMethod("NameOfMthodToInvoke", arguments); 

//arguments need to be like- java.lang.Integer.class 
//like:- Method method=obj.getMethod("doubleIt",java.lang.Integer.class); 

bước 3: - Gọi Phương Bằng cách vượt qua Instance của đối tượng và lập luận

Object obj2= method.invoke(obj.newInstance(), id); 
//like :- method.invoke(obj.newInstance(), 45); 

BẠN CÓ THỂ LÀM BƯỚC 2 NHƯNG NÀY C 01NG

(khi bạn không biết phương pháp đặc biệt tồn tại trong một lớp học mà bạn rà soát tất cả phương pháp lặp mảng phương pháp của)

Method[] methods=obj.getMethods(); 

Method method=null; 

for(int i=0;i&lt;methods.length();i++) 

{ 

if(method[1].getName().equals("methodNameWeAreExpecting")) 

{ 

method=method[i]; 

} 

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