¿Cómo paso una clase como parámetro en Java?

136

¿Hay alguna forma de pasar la clase como parámetro en Java y activar algunos métodos desde esa clase?

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

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

Estoy usando Google Web Toolkit y no admite la reflexión.

Michael Dorner
fuente

Respuestas:

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

Cómo invocar el método usando la reflexión

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

Ver también

Jigar Joshi
fuente
¿Y cómo disparo el constructor predeterminado o algunos métodos en esa clase?
lo siento, olvidé agregar sobre el kit de herramientas web de Google y esas cosas, estoy usando el kit de herramientas web de Google y no admite la reflexión.
1
Mira aquí y aquí también esto
Jigar Joshi
¡Quiero hablar sobre la filosofía! ¿Es la clase un tipo de datos 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();
}

Para llamar al método, lo llama de esta manera:

callingMethod(ClassBeingCalled.class);
Olanrewaju O. Joseph
fuente
El autor de la pregunta también quería usar el constructor de la clase. Eso no es fácil, y nadie lo está abordando aquí. Esta publicación ofrece una opción (lea todos los comentarios, porque la respuesta aceptada no funciona): stackoverflow.com/questions/234600/… . Sin embargo, es bastante complicado, y las advertencias del compilador que obtienes sugieren que no querían que la gente hiciera esto con Java. Mucho más fácil en Python
:)
9

Construye tu método para aceptarlo.

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

Llame al método

printClassNameAndCreateList(SomeClass.class);

También puede restringir el tipo de clase, por ejemplo, este es uno de los métodos de una biblioteca que hice:

protected Class postExceptionActivityIn;

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

Para más información, busque Reflexión y Genéricos.

Joshua Gainey
fuente
3

Utilizar

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

A Classtambién es un objeto Java, por lo que puede referirse a él utilizando su tipo.

Lea más sobre esto en la documentación oficial .

darioo
fuente
2

Este tipo de cosas no es fácil. Aquí hay un método que llama a un método estático:

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

Actualización: Espera, acabo de ver la etiqueta gwt en la pregunta. No puedes usar la reflexión en GWT

Sean Patrick Floyd
fuente
1

No estoy seguro de lo que está tratando de lograr, pero es posible que desee considerar que aprobar una clase puede no ser lo que realmente necesita hacer. En muchos casos, tratar con una clase como esta se encapsula fácilmente dentro de un patrón de fábrica de algún tipo y el uso de eso se realiza a través de una interfaz. Aquí hay uno de docenas de artículos sobre ese patrón: http://today.java.net/pub/a/today/2005/03/09/factory.html

El uso de una clase dentro de una fábrica se puede lograr de varias maneras, especialmente al tener un archivo de configuración que contiene el nombre de la clase que implementa la interfaz requerida. Entonces la fábrica puede encontrar esa clase desde dentro de la ruta de clase y construirla como un objeto de la interfaz especificada.

Jorel
fuente
0

Como dijiste, GWT no admite la reflexión. Debe usar el enlace diferido en lugar de la reflexión, o una biblioteca de terceros como gwt-ent para el soporte de reflexión en la capa gwt.

Gursel Koca
fuente
-1

Eche un vistazo al tutorial de reflexión y la API de reflexión de Java:

https://community.oracle.com/docs/DOC-983192 ingrese la descripción del enlace aquí

y

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

Marcus Gründler
fuente
OP declaró claramente que está usando GWT que no admite la reflexión
Knarf
2
La pregunta fue editada mucho después de mi respuesta. La pregunta original no contenía esa pista. La respuesta aceptada también se refiere a la reflexión por cierto.
Marcus Gründler
-1

Clase como paramater. Ejemplo.

Tres clases:

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

}

En la clase, el método Terminal hackCar () toma la clase TestCar como parámetro.

romangorbenko.com
fuente
1
uhm no, está tomando una instancia de TestCar
towc