Bagaimana cara melewatkan kelas sebagai parameter di Java?


142

Apakah ada cara untuk melewatkan kelas sebagai parameter di Java dan mengaktifkan beberapa metode dari kelas itu?

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

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

Saya menggunakan Google Web Toolkit dan tidak mendukung refleksi.

Jawaban:


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

Bagaimana memanggil metode menggunakan refleksi

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

Lihat juga


dan bagaimana cara mengaktifkan konstruktor default atau beberapa metode di kelas itu?

maaf saya lupa menambahkan tentang google web tool kit dan sejenisnya, saya menggunakan google web toolkit dan tidak mendukung refleksi.

1
Lihat di sini dan di sini juga ini
Jigar Joshi

Saya ingin berbicara tentang filosofi! Apakah Kelas tipe data di Java?
Milad Rahimi

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

Untuk memanggil metode tersebut, Anda menyebutnya seperti ini:

callingMethod(ClassBeingCalled.class);

Penanya juga ingin menggunakan konstruktor kelas. Itu tidak mudah, dan tidak ada yang membahasnya di sini. Posting ini memberikan opsi (baca semua komentar, karena jawaban yang diterima tidak berfungsi): stackoverflow.com/questions/234600/… . Ini cukup berantakan, dan peringatan kompiler yang Anda dapatkan menyarankan mereka tidak ingin orang melakukan ini dengan Java. Jauh lebih mudah dengan Python
:)

9

Bangun metode Anda untuk menerimanya-

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

Panggil metode-

printClassNameAndCreateList(SomeClass.class);

Anda juga dapat membatasi jenis kelas, misalnya, ini adalah salah satu metode dari perpustakaan yang saya buat-

protected Class postExceptionActivityIn;

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

Untuk informasi lebih lanjut, cari Refleksi dan Generik.


3

Menggunakan

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

A Classjuga merupakan objek Java, jadi Anda bisa merujuknya menggunakan tipenya.

Baca lebih lanjut tentang itu dari dokumentasi resmi .


2

Hal semacam ini tidak mudah. Berikut adalah metode yang memanggil metode statis:

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

Pembaruan: Tunggu, saya baru saja melihat tag gwt di pertanyaan. Anda tidak dapat menggunakan refleksi di GWT


1

Saya tidak yakin apa yang ingin Anda capai, tetapi Anda mungkin ingin mempertimbangkan bahwa lulus kelas mungkin bukanlah hal yang benar-benar perlu Anda lakukan. Dalam banyak kasus, berurusan dengan Kelas seperti ini dengan mudah dienkapsulasi dalam pola pabrik dari beberapa jenis dan penggunaannya dilakukan melalui antarmuka. inilah salah satu dari lusinan artikel tentang pola itu: http://today.java.net/pub/a/today/2005/03/09/factory.html

menggunakan kelas di dalam pabrik dapat dilakukan dengan berbagai cara, terutama dengan memiliki file konfigurasi yang berisi nama kelas yang mengimplementasikan antarmuka yang diperlukan. Kemudian pabrik dapat menemukan kelas itu dari dalam jalur kelas dan membangunnya sebagai objek antarmuka yang ditentukan.


0

Seperti yang Anda katakan, GWT tidak mendukung refleksi. Anda harus menggunakan deferred binding, bukan refleksi, atau library pihak ketiga seperti gwt-ent untuk dukungan refleksi di lapisan gwt.




-1

Kelas sebagai paramater. Contoh.

Tiga kelas:

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

}

Dalam metode Terminal kelas hackCar () gunakan kelas TestCar sebagai parameter.


1
uhm tidak, ini mengambil contoh TestCar
towc
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.