Come faccio a passare una classe come parametro in Java?


136

Esiste un modo per passare la classe come parametro in Java e attivare alcuni metodi di quella classe?

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

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

Sto utilizzando Google Web Toolkit e non supporta la riflessione.

Risposte:


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

Come invocare il metodo usando la riflessione

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

Vedi anche


e come posso attivare il costruttore predefinito o alcuni metodi in quella classe?

scusate ho dimenticato di aggiungere il kit di strumenti web di Google e roba del genere, sto usando google web toolkit e non supporta la riflessione.

1
Guarda qui e qui anche questo
Jigar Joshi,

Voglio parlare della filosofia! Class è un tipo di dati 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();
}

Per chiamare il metodo, lo si chiama in questo modo:

callingMethod(ClassBeingCalled.class);

Il richiedente voleva anche usare il costruttore della classe. Non è facile e nessuno lo sta affrontando qui. Questo post fornisce un'opzione (leggi tutti i commenti, perché la risposta accettata non funziona): stackoverflow.com/questions/234600/… . È piuttosto disordinato, tuttavia, e gli avvisi del compilatore che ricevi suggeriscono che non volevano che la gente lo facesse con Java. Molto più facile in Python
:)

9

Costruisci il tuo metodo per accettarlo-

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

Chiama il metodo

printClassNameAndCreateList(SomeClass.class);

Puoi anche limitare il tipo di classe, ad esempio, questo è uno dei metodi di una libreria che ho creato-

protected Class postExceptionActivityIn;

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

Per ulteriori informazioni, cerca Reflection and Generics.


3

Uso

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

A Classè anche un oggetto Java, quindi puoi fare riferimento ad esso usando il suo tipo.

Maggiori informazioni sulla documentazione ufficiale .


2

Questo genere di cose non è facile. Ecco un metodo che chiama un metodo statico:

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

Aggiornamento: aspetta, ho appena visto il tag gwt sulla domanda. Non puoi usare la riflessione in GWT


1

Non sono sicuro di ciò che stai cercando di realizzare, ma potresti voler considerare che passare una lezione potrebbe non essere quello che devi davvero fare. In molti casi, trattare con Class come questa è facilmente incapsulato all'interno di un modello di fabbrica di qualche tipo e l'uso di ciò avviene attraverso un'interfaccia. ecco uno dei dozzine di articoli su quel modello: http://today.java.net/pub/a/today/2005/03/09/factory.html

l'utilizzo di una classe all'interno di una factory può essere realizzato in vari modi, in particolare con un file di configurazione che contiene il nome della classe che implementa l'interfaccia richiesta. Quindi la factory può trovare quella classe all'interno del percorso della classe e costruirla come oggetto dell'interfaccia specificata.


0

Come hai detto, GWT non supporta la riflessione. Dovresti usare la rilegatura differita invece di reflection o una libreria di terze parti come gwt-ent per il supporto del riflesso sul livello gwt.



-1

OP ha dichiarato chiaramente che sta usando GWT che non supporta la riflessione
Knarf,

2
La domanda è stata modificata molto dopo la mia risposta. La domanda originale non conteneva quel suggerimento. A proposito, la risposta accettata si riferisce anche alla riflessione.
Marcus Gründler,

-1

Classe come paramater. Esempio.

Tre classi:

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

}

Nella classe Terminale metodo hackCar () accetta la classe TestCar come parametro.


1
ehm no, sta prendendo un'istanza di TestCar
rimorchiato il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.