Comment passer une classe en tant que paramètre en Java?

136

Existe-t-il un moyen de passer la classe en tant que paramètre dans Java et de déclencher certaines méthodes de cette classe?

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

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

J'utilise Google Web Toolkit et il ne prend pas en charge la réflexion.

Michael Dorner
la source

Réponses:

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

Comment invoquer une méthode en utilisant la réflexion

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

Regarde aussi

Jigar Joshi
la source
et comment déclencher le constructeur par défaut ou certaines méthodes de cette classe?
Désolé, j'ai oublié d'ajouter à propos du kit d'outils Web Google et d'autres choses, j'utilise la boîte à outils Web Google et cela ne prend pas en charge la réflexion.
1
Regardez ici et ici aussi ceci
Jigar Joshi
Je veux parler de la philosophie! La classe est-elle un type de données en 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();
}

Pour appeler la méthode, vous l'appelez de cette façon:

callingMethod(ClassBeingCalled.class);
Olanrewaju O. Joseph
la source
Le demandeur voulait également utiliser le constructeur de la classe. Ce n'est pas facile, et personne ne s'en occupe ici. Cet article fournit une option (lisez tous les commentaires, car la réponse acceptée ne fonctionne pas): stackoverflow.com/questions/234600/… . C'est assez compliqué, cependant, et les avertissements du compilateur que vous recevez suggèrent qu'ils ne voulaient pas que les gens le fassent avec Java. Beaucoup plus facile en Python
:)
9

Construisez votre méthode pour l'accepter-

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

Appelez la méthode-

printClassNameAndCreateList(SomeClass.class);

Vous pouvez également restreindre le type de classe, par exemple, c'est l'une des méthodes d'une bibliothèque que j'ai créée -

protected Class postExceptionActivityIn;

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

Pour plus d'informations, recherchez Reflection and Generics.

Joshua Gainey
la source
3

Utilisation

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

A Classest également un objet Java, vous pouvez donc y faire référence en utilisant son type.

En savoir plus à ce sujet dans la documentation officielle .

darioo
la source
2

Ce genre de chose n'est pas facile. Voici une méthode qui appelle une méthode statique:

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

Mise à jour: Attendez, je viens de voir la balise gwt sur la question. Vous ne pouvez pas utiliser la réflexion dans GWT

Sean Patrick Floyd
la source
1

Je ne suis pas sûr de ce que vous essayez d'accomplir, mais vous voudrez peut-être considérer que réussir un cours n'est peut-être pas ce que vous devez vraiment faire. Dans de nombreux cas, traiter une classe comme celle-ci est facilement encapsulé dans un modèle d'usine d'un certain type et l'utilisation de cela se fait via une interface. voici l'un des dizaines d'articles sur ce modèle: http://today.java.net/pub/a/today/2005/03/09/factory.html

l'utilisation d'une classe dans une fabrique peut être accomplie de différentes manières, notamment en ayant un fichier de configuration contenant le nom de la classe qui implémente l'interface requise. Ensuite, la fabrique peut trouver cette classe à partir du chemin de classe et la construire en tant qu'objet de l'interface spécifiée.

Jorel
la source
0

Comme vous l'avez dit, GWT ne prend pas en charge la réflexion. Vous devez utiliser la liaison différée au lieu de la réflexion, ou une bibliothèque tierce telle que gwt-ent pour la prise en charge de la réflexion au niveau de la couche gwt.

Gursel Koca
la source
-1

Jetez un œil au tutoriel de réflexion et à l'API de réflexion de Java:

https://community.oracle.com/docs/DOC-983192 entrez la description du lien ici

et

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

Marcus Gründler
la source
OP a clairement indiqué qu'il utilise GWT qui ne prend pas en charge la réflexion
Knarf
2
La question a été modifiée longtemps après ma réponse. La question originale ne contenait pas cet indice. La réponse acceptée fait également référence à la réflexion en passant.
Marcus Gründler
-1

Classez comme paramater. Exemple.

Trois classes:

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

}

Dans la classe Terminal, la méthode hackCar () prend la classe TestCar comme paramètre.

romangorbenko.com
la source
1
euh non, il prend une instance de TestCar
towc