Wie übergebe ich eine Klasse als Parameter in Java?

136

Gibt es eine Möglichkeit, eine Klasse als Parameter in Java zu übergeben und einige Methoden aus dieser Klasse auszulösen?

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

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

Ich verwende Google Web Toolkit und es unterstützt keine Reflexion.

Michael Dorner
quelle

Antworten:

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

Aufrufen der Methode mithilfe der Reflexion

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

Siehe auch

Jigar Joshi
quelle
und wie feuere ich den Standardkonstruktor oder einige Methoden in dieser Klasse ab?
Es tut mir leid, dass ich vergessen habe, etwas über das Google Web Tool Kit und andere Dinge hinzuzufügen. Ich verwende das Google Web Toolkit und es unterstützt keine Reflexion.
1
Schau hier und hier auch das
Jigar Joshi
Ich möchte über die Philosophie sprechen! Ist Class ein Datentyp in Java?
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();
}

Um die Methode aufzurufen, rufen Sie sie folgendermaßen auf:

callingMethod(ClassBeingCalled.class);
Olanrewaju O. Joseph
quelle
Der Fragesteller wollte auch den Konstruktor der Klasse verwenden. Das ist nicht einfach und niemand spricht es hier an. Dieser Beitrag bietet eine Option (lesen Sie alle Kommentare, da die akzeptierte Antwort nicht funktioniert): stackoverflow.com/questions/234600/… . Es ist jedoch ziemlich chaotisch und die Compiler-Warnungen deuten darauf hin, dass sie nicht wollten, dass Leute dies mit Java tun. Viel einfacher in Python
:)
9

Konstruieren Sie Ihre Methode, um sie zu akzeptieren.

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

Rufen Sie die Methode auf.

printClassNameAndCreateList(SomeClass.class);

Sie können auch den Klassentyp einschränken. Dies ist beispielsweise eine der Methoden aus einer Bibliothek, die ich erstellt habe.

protected Class postExceptionActivityIn;

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

Weitere Informationen finden Sie unter Reflection and Generics.

Joshua Gainey
quelle
4

Verwenden

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

A Classist auch ein Java-Objekt, sodass Sie mithilfe seines Typs darauf verweisen können.

Lesen Sie mehr darüber aus der offiziellen Dokumentation .

Darioo
quelle
2

So etwas ist nicht einfach. Hier ist eine Methode, die eine statische Methode aufruft:

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

Update: Warten Sie, ich habe gerade das GWT-Tag auf der Frage gesehen. Sie können die Reflexion in GWT nicht verwenden

Sean Patrick Floyd
quelle
1

Ich bin mir nicht sicher, was Sie erreichen wollen, aber Sie möchten vielleicht in Betracht ziehen, dass das Bestehen einer Klasse möglicherweise nicht das ist, was Sie wirklich tun müssen. In vielen Fällen lässt sich der Umgang mit einer solchen Klasse leicht in ein Fabrikmuster eines Typs einkapseln, und die Verwendung erfolgt über eine Schnittstelle. Hier ist einer von Dutzenden Artikeln zu diesem Muster: http://today.java.net/pub/a/today/2005/03/09/factory.html

Die Verwendung einer Klasse innerhalb einer Factory kann auf verschiedene Arten erfolgen, insbesondere durch eine Konfigurationsdatei, die den Namen der Klasse enthält, die die erforderliche Schnittstelle implementiert. Dann kann die Factory diese Klasse aus dem Klassenpfad heraus finden und als Objekt der angegebenen Schnittstelle erstellen.

Jorel
quelle
0

Wie Sie sagten, unterstützt GWT keine Reflexion. Sie sollten die verzögerte Bindung anstelle der Reflexion oder eine Bibliothek eines Drittanbieters wie gwt-ent für die Reflexionsunterstützung auf der gwt-Ebene verwenden.

Gursel Koca
quelle
-1

Schauen Sie sich das Reflection-Tutorial und die Reflection-API von Java an:

https://community.oracle.com/docs/DOC-983192 Geben Sie hier die Linkbeschreibung ein

und

http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html

Marcus Gründler
quelle
OP erklärte klar, dass er GWT verwendet, das keine Reflexion unterstützt
Knarf
2
Die Frage wurde lange nach meiner Antwort bearbeitet. Die ursprüngliche Frage enthielt diesen Hinweis nicht. Die akzeptierte Antwort bezieht sich übrigens auch auf Reflexion.
Marcus Gründler
-1

Klasse als Parameter. Beispiel.

Drei Klassen:

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

}

In der Klasse Terminal Methode hackCar () nehmen Sie die Klasse TestCar als Parameter.

romangorbenko.com
quelle
1
ähm nein, es dauert eine Instanz von TestCar
Towc