Gọi một phương thức tĩnh bằng phản xạ


198

Tôi muốn gọi mainphương thức tĩnh. Tôi đã nhận được đối tượng của kiểu Class, nhưng tôi không thể tạo một thể hiện của lớp đó và cũng không thể gọi staticphương thức main.

Câu trả lời:


290
// String.class here is the parameter type, that might not be the case with you
Method method = clazz.getMethod("methodName", String.class);
Object o = method.invoke(null, "whatever");

Trong trường hợp phương pháp là sử dụng riêng getDeclaredMethod()thay vì getMethod(). Và gọi setAccessible(true)đối tượng phương thức.


49

Fromthe Javadoc của Phương thức.invoke ():

Nếu phương thức cơ bản là tĩnh, thì đối số obj đã chỉ định sẽ bị bỏ qua. Nó có thể là null.

Điều gì xảy ra khi bạn

Lớp klass = ...;
Phương thức m = klass.getDeclaredMethod (methodName, paramtypes);
m.invoke (null, args)

13
String methodName= "...";
String[] args = {};

Method[] methods = clazz.getMethods();
for (Method m : methods) {
    if (methodName.equals(m.getName())) {
        // for static methods we can use null as instance of class
        m.invoke(null, new Object[] {args});
        break;
    }
}

11
Tại sao không sử dụng getMethod với tên chính xác thay vì lặp qua tất cả các phương thức?
mjaggard

11
Đôi khi, việc lặp và tìm phương thức theo tên dễ dàng hơn nhiều so với sử dụng getMethod vì getMethod (hoặc getDeclaredMethod) yêu cầu bạn phải thực hiện các loại tham số rất chi tiết. Nó chỉ phụ thuộc vào vấn đề hiệu quả vi mô - Lặp lại Java rất nhanh vì vậy trừ khi bạn gọi phương thức hàng triệu lần trong một số vòng lặp bên trong thì việc lặp lại sẽ đủ nhanh
Tony Eastwood

2
Ngoài ra, trong một tình huống thực tế hơn, có lẽ bạn sẽ chỉ tìm thấy phương thức một lần ngay cả khi bạn sẽ sử dụng sự phản chiếu để gọi nó nhiều lần. Vì vậy, chi phí thêm khi tìm thấy nó là không quan trọng.
RenniePet

4
Gonna có một thời gian tồi tệ với các phương pháp quá tải mặc dù.
Ulysse Mizrahi

1
@UlysseMizrahi tất cả phụ thuộc vào những gì bạn khớp, nhưng vâng, nếu bạn đang viết mã thư viện, có thể nguy hiểm nếu chỉ dựa vào tên. Tôi thường kiểm tra một chú thích cụ thể hoặc một chữ ký phương thức cụ thể, như "phương thức tĩnh lấy Chuỗi và trả về một thể hiện của lớp", sau đó khẳng định rằng chỉ có một phương thức như vậy được tìm thấy.
cobbzilla

0
public class Add {
    static int add(int a, int b){
        return (a+b);
    }
}

Trong ví dụ trên, 'add' là một phương thức tĩnh lấy hai số nguyên làm đối số.

Đoạn mã sau được sử dụng để gọi phương thức 'thêm' với đầu vào 1 và 2.

Class myClass = Class.forName("Add");
Method method = myClass.getDeclaredMethod("add", int.class, int.class);
Object result = method.invoke(null, 1, 2);

Liên kết tham khảo .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.