Bir sınıfı Java'da parametre olarak nasıl iletirim?


136

Java'da sınıfı parametre olarak geçirmenin ve bu sınıftan bazı yöntemleri tetiklemenin bir yolu var mı?

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

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

Google Web Araç Seti kullanıyorum ve yansımayı desteklemiyor.

Yanıtlar:


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

Yansıma kullanarak yöntem çağırma

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

Ayrıca Bkz.


ve varsayılan kurucuyu veya bu sınıftaki bazı yöntemleri nasıl tetikleyebilirim?

üzgünüm google web araç kiti ve şeyler hakkında eklemek unuttum, im google web araç seti kullanarak im ve yansıma desteklemiyor.

1
Bak burada ve burada da bu
Jigar Joshi

Felsefe hakkında konuşmak istiyorum! Sınıf Java'da bir veri türü mü?
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();
}

Yöntemi çağırmak için şu şekilde adlandırırsınız:

callingMethod(ClassBeingCalled.class);

Asker de sınıfın yapıcısını kullanmak istedi. Bu kolay değil ve kimse burada ele almıyor. Bu gönderi bir seçenek sunuyor (kabul edilen cevap işe yaramadığından tüm yorumları okuyun): stackoverflow.com/questions/234600/… . Yine de oldukça dağınık ve aldığınız derleyici uyarıları, insanların bunu Java ile yapmasını istemediklerini gösteriyor. Python'da çok daha kolay
:)

9

Kabul etmek için yönteminizi oluşturun-

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

Yöntemi çağırın

printClassNameAndCreateList(SomeClass.class);

Sınıf türünü de kısıtlayabilirsiniz, örneğin bu, yaptığım bir kitaplıktaki yöntemlerden biridir.

protected Class postExceptionActivityIn;

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

Daha fazla bilgi için Yansıma ve Jenerikleri arayın.


3

kullanım

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

A Classayrıca bir Java nesnesidir, bu nedenle türünü kullanarak ona başvurabilirsiniz.

Bununla ilgili daha fazla bilgiyi resmi belgelerden okuyun .


2

Bu tür şeyler kolay değil. Statik bir yöntem çağıran bir yöntem:

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

Güncelleme: Bekle, soruda gwt etiketini gördüm. GWT'de yansımayı kullanamazsınız


1

Neyi başarmaya çalıştığınızdan emin değilim, ancak bir sınıfı geçmenin gerçekten yapmanız gereken şey olmadığını düşünebilirsiniz. Çoğu durumda, bunun gibi Class ile uğraşmak, bir tür fabrika modelinde kolayca kapsüllenir ve bunun kullanımı bir arayüz üzerinden yapılır. İşte bu model üzerinde onlarca makaleden biri: http://today.java.net/pub/a/today/2005/03/09/factory.html

bir fabrika içinde bir sınıfın kullanılması, özellikle gerekli arabirimi uygulayan sınıfın adını içeren bir yapılandırma dosyasına sahip olmak suretiyle çeşitli şekillerde gerçekleştirilebilir. Daha sonra fabrika bu sınıfı sınıf yolundan bulabilir ve belirtilen arabirimin bir nesnesi olarak oluşturabilir.


0

Dediğiniz gibi GWT yansımayı desteklemiyor. Yansıma yerine ertelenmiş ciltleme veya gwt katmanında yansıma desteği için gwt-ent gibi üçüncü taraf kitaplığı kullanmalısınız .



-1

OP, yansımayı desteklemeyen GWT kullandığını açıkça belirtti
Knarf

2
Soru, cevabımdan çok sonra düzenlenmiştir. Orijinal soru bu ipucunu içermiyordu. Kabul edilen cevap aynı zamanda bu arada yansımayı ifade eder.
Marcus Gründler

-1

Paramater olarak sınıf. Misal.

Üç sınıf:

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

}

Sınıfta Terminal yöntemi hackCar () parametre olarak sınıf TestCar alır.


1
uhm hayır, TestCar'ın bir örneğini alıyor
towc
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.