Làm cách nào để tôi vượt qua một lớp làm tham số trong Java?


136

Có cách nào để vượt qua lớp như một tham số trong Java và kích hoạt một số phương thức từ lớp đó không?

void main()
{
    callClass(that.class)
}

void callClass(???? classObject)
{
    classObject.somefunction
    // or 
    new classObject()
    //something like that ?
}

Tôi đang sử dụng Google Web Toolkit và nó không hỗ trợ phản chiếu.

Câu trả lời:


129
public void foo(Class c){
        try {
            Object ob = c.newInstance();
        } catch (InstantiationException ex) {
            Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

Cách gọi phương thức bằng phản xạ

 import java.lang.reflect.*;


   public class method2 {
      public int add(int a, int b)
      {
         return a + b;
      }

      public static void main(String args[])
      {
         try {
           Class cls = Class.forName("method2");
           Class partypes[] = new Class[2];
            partypes[0] = Integer.TYPE;
            partypes[1] = Integer.TYPE;
            Method meth = cls.getMethod(
              "add", partypes);
            method2 methobj = new method2();
            Object arglist[] = new Object[2];
            arglist[0] = new Integer(37);
            arglist[1] = new Integer(47);
            Object retobj 
              = meth.invoke(methobj, arglist);
            Integer retval = (Integer)retobj;
            System.out.println(retval.intValue());
         }
         catch (Throwable e) {
            System.err.println(e);
         }
      }
   }

Cũng thấy


và làm thế nào để tôi khởi chạy constructor mặc định hoặc một số phương thức trong lớp đó?

xin lỗi tôi đã quên thêm về bộ công cụ web google và các công cụ, tôi đang sử dụng bộ công cụ web của google và nó không hỗ trợ sự phản chiếu.

1
Nhìn vào đâyđây cũng thế này
Jigar Joshi

Tôi muốn nói về triết lý! Class có phải là kiểu dữ liệu trong Java không?
Milad Rahimi

40
public void callingMethod(Class neededClass) {
    //Cast the class to the class you need
    //and call your method in the class
    ((ClassBeingCalled)neededClass).methodOfClass();
}

Để gọi phương thức, bạn gọi nó theo cách này:

callingMethod(ClassBeingCalled.class);

Người hỏi cũng muốn sử dụng hàm tạo của lớp. Điều đó không dễ, và không ai giải quyết nó ở đây. Bài đăng này cung cấp một tùy chọn (đọc tất cả các ý kiến, vì câu trả lời được chấp nhận không hoạt động): stackoverflow.com/questions/234600/ . Mặc dù vậy, nó khá lộn xộn và trình biên dịch cảnh báo bạn nhận được đề xuất rằng họ không muốn mọi người làm điều này với Java. Dễ dàng hơn nhiều trong Python :)
Andrew Puglionesi

9

Xây dựng phương pháp của bạn để chấp nhận nó-

public <T> void printClassNameAndCreateList(Class<T> className){
    //example access 1
    System.out.print(className.getName());

    //example access 2
    ArrayList<T> list = new ArrayList<T>();
    //note that if you create a list this way, you will have to cast input
    list.add((T)nameOfObject);
}

Gọi phương thức-

printClassNameAndCreateList(SomeClass.class);

Bạn cũng có thể hạn chế loại lớp, ví dụ, đây là một trong những phương thức từ thư viện tôi đã tạo-

protected Class postExceptionActivityIn;

protected <T extends PostExceptionActivity>  void  setPostExceptionActivityIn(Class <T> postExceptionActivityIn) {
    this.postExceptionActivityIn = postExceptionActivityIn;
}

Để biết thêm thông tin, tìm kiếm Reflection và Generics.


4

Sử dụng

void callClass(Class classObject)
{
   //do something with class
}

A Classcũng là một đối tượng Java, vì vậy bạn có thể tham chiếu đến nó bằng cách sử dụng kiểu của nó.

Đọc thêm về nó từ tài liệu chính thức .


2

Loại điều này không dễ dàng. Đây là một phương thức gọi một phương thức tĩnh:

public static Object callStaticMethod(
    // class that contains the static method
    final Class<?> clazz,
    // method name
    final String methodName,
    // optional method parameters
    final Object... parameters) throws Exception{
    for(final Method method : clazz.getMethods()){
        if(method.getName().equals(methodName)){
            final Class<?>[] paramTypes = method.getParameterTypes();
            if(parameters.length != paramTypes.length){
                continue;
            }
            boolean compatible = true;
            for(int i = 0; i < paramTypes.length; i++){
                final Class<?> paramType = paramTypes[i];
                final Object param = parameters[i];
                if(param != null && !paramType.isInstance(param)){
                    compatible = false;
                    break;
                }

            }
            if(compatible){
                return method.invoke(/* static invocation */null,
                    parameters);
            }
        }
    }
    throw new NoSuchMethodException(methodName);
}

Cập nhật: Đợi đã, tôi chỉ thấy thẻ gwt trong câu hỏi. Bạn không thể sử dụng sự phản chiếu trong GWT


1

Tôi không chắc chắn những gì bạn đang cố gắng thực hiện, nhưng bạn có thể muốn xem xét rằng việc vượt qua một lớp học có thể không phải là điều bạn thực sự cần phải làm. Trong nhiều trường hợp, việc xử lý Class như thế này dễ dàng được gói gọn trong một kiểu mẫu của một số loại và việc sử dụng nó được thực hiện thông qua một giao diện. đây là một trong hàng tá bài viết về mẫu đó: http://today.java.net/pub/a/today/2005/03/09/factory.html

sử dụng một lớp trong một nhà máy có thể được thực hiện bằng nhiều cách khác nhau, đáng chú ý nhất là có một tệp cấu hình có chứa tên của lớp thực hiện giao diện được yêu cầu. Sau đó, nhà máy có thể tìm thấy lớp đó từ bên trong đường dẫn lớp và xây dựng nó như một đối tượng của giao diện đã chỉ định.


0

Như bạn đã nói GWT không hỗ trợ phản ánh. Bạn nên sử dụng liên kết hoãn lại thay vì phản chiếu hoặc thư viện bên thứ ba như gwt-ent cho suppport phản chiếu ở lớp gwt.



-1

OP tuyên bố rõ ràng anh ta đang sử dụng GWT không hỗ trợ phản chiếu
Knarf

2
Câu hỏi đã được chỉnh sửa rất lâu sau câu trả lời của tôi. Câu hỏi ban đầu không chứa gợi ý đó. Câu trả lời được chấp nhận cũng đề cập đến sự phản ánh bằng cách này.
Marcus Gründler

-1

Đẳng cấp như paramater. Thí dụ.

Ba lớp:

class TestCar {

    private int UnlockCode = 111;
    protected boolean hasAirCondition = true;
    String brand = "Ford";
    public String licensePlate = "Arizona 111";
}

-

class Terminal {

public void hackCar(TestCar car) {
     System.out.println(car.hasAirCondition);
     System.out.println(car.licensePlate);
     System.out.println(car.brand);
     }
}

-

class Story {

    public static void main(String args[]) {
        TestCar testCar = new TestCar();
        Terminal terminal = new Terminal();
        terminal.hackCar(testCar);
    }

}

Trong lớp Terminal phương thức hackCar () lấy lớp TestCar làm tham số.


1
uhm không, nó lấy một ví dụ của TestCar
kéo dài
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.