Foros del Web » Programación para mayores de 30 ;) » Java »

Dudas con Invoke()

Estas en el tema de Dudas con Invoke() en el foro de Java en Foros del Web. Hola, tengo una duda, no sé como utilizar invoke() para pasar un Array como parámetro. Tengo 2 clases: - Persona (para el ejemplo considero solo ...
  #1 (permalink)  
Antiguo 12/04/2007, 23:47
Avatar de buhoMc  
Fecha de Ingreso: abril-2007
Mensajes: 5
Antigüedad: 17 años
Puntos: 0
Información Dudas con Invoke()

Hola, tengo una duda, no sé como utilizar invoke() para pasar un Array como parámetro.

Tengo 2 clases:
- Persona (para el ejemplo considero solo la propiedad edad).
- Personas (que tiene un Array de personas, Persona[] personas).

La función setJB(String edad) retorna una instancia de Persona, inicializada con la edad enviada.

public Object setJB(String edad)
{
Object jb = null;
try{
jb = Beans.instantiate(null, "clases.Persona");
Class[] argTypes = { String.class };
Object[] ctorArgs = { edad };
Object[] setterArgs = new Object[] {
Byte.class.getConstructor(argTypes).newInstance(ct orArgs) };
PropertyDescriptor pd = getPropertyDescriptors(jb.getClass())[1];
Method setter = pd.getWriteMethod();
if (setterArgs != null)
setter.invoke(jb, setterArgs);
else
System.out.println("Error");
Method printer = jb.getClass().getMethod("print", null);
printer.invoke(jb, null);
}catch(Exception e){System.out.println(e);}
return jb;
}

Hasta aquí todo va bien, el problema está en el procedimiento setJB1(), que tal como está, solo puede crear una instancia de Personas y pasar un parámetro de tipo Persona recibido de setJB(edad), esto modificando la clase Personas para que en lugar de recibir un Array (Persona[] personas) reciba una instancia (Persona persona). Lo que deseo es precisamente pasar un Array de tipo Persona {argBean1, argBean2} en lugar de una sola instancia Persona.

public void setJB1()
{
Object jb = null;
try{
jb = Beans.instantiate(null, "clases.Personas");

Object argBean1 = setJB("23");
Object argBean2 = setJB("24");

Object[] setterArgs = new Object[] { argBean1 };

PropertyDescriptor pd = getPropertyDescriptors(jb.getClass())[1];
Method setter = pd.getWriteMethod();
if (setterArgs != null)
setter.invoke(jb, setterArgs);
else
System.out.println("Error");
Method printer = jb.getClass().getMethod("print", null);
printer.invoke(jb, null);

}catch(Exception e){System.out.println(e);}
}

Gracias
  #2 (permalink)  
Antiguo 13/04/2007, 01:58
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 20 años, 6 meses
Puntos: 51
Re: Dudas con Invoke()

Has probado...
Código:
Object[] setterArgs = new Object[] { new Persona[]{argBean1,argBean2} };
?
  #3 (permalink)  
Antiguo 13/04/2007, 10:12
Avatar de buhoMc  
Fecha de Ingreso: abril-2007
Mensajes: 5
Antigüedad: 17 años
Puntos: 0
Re: Dudas con Invoke()

Excelente, si funciona con unos pocos ajustes:

Object[] setterArgs = new Object[] { new Persona[]{(Persona)argBean1,(Persona)argBean2} };

muchas gracias ya tengo la idea, pero estoy buscando hacerlo más genérico es decir no tener que indicar directamente el tipo de objeto (Persona), sino de forma indirecta para lo cual probé los siguientes códigos pero no funciona.

Object[] setterArgs = new Object[] { new Object[] {argBean1, argBean2} };

java.lang.IllegalArgumentException: argument type mismatch

**********

Class[] argTypes = { Class.forName("clases.Persona") };
Object[] ctorArgs = { new Object[] {argBean1, argBean2} };
Object[] setterArgs = new Object[] { Class.forName("clases.Persona").getConstructor(arg Types).newInstance(ctorArgs) };

java.lang.NoSuchMethodException: clases.Persona.<init>(clases.Persona)

**********

Este último creo que va por buen camino, pero no se que está mal.

Gracias nuevamente.
  #4 (permalink)  
Antiguo 13/04/2007, 11:12
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 20 años, 6 meses
Puntos: 51
Re: Dudas con Invoke()

Ah, claro. No me habia fijado en que argBean1 y 2 eran del tipo Object y por eso requieren un "casting".

Para hacerlo genericamente, podrias usar la clase java.lang.reflect.Array que te permite crear instancias de arrays de un tipo pasandole la clase como parametro. Y luego puedes usar ese array generico como parametro.

S!
  #5 (permalink)  
Antiguo 17/04/2007, 17:49
Avatar de buhoMc  
Fecha de Ingreso: abril-2007
Mensajes: 5
Antigüedad: 17 años
Puntos: 0
Re: Dudas con Invoke()

Hola, estuve viendo sobre "java.lang.reflect.Array", pero aun no he podido llegar a un código que funcione, ¿Cómo sería el código usando el Array? o ¿Cómo podría hacer un casting de la clase Persona? por ejemplo a partir de este código:

Código:
Class.forName("clases.Persona")
la idea es reemplazar esta forma de casting ((Persona)argBean1) por otra donde sólo use el nombre de la clase.
  #6 (permalink)  
Antiguo 18/04/2007, 00:53
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 20 años, 6 meses
Puntos: 51
Re: Dudas con Invoke()

Si quieres hacerlo generico, no puede haber "casting" al tipo en concreto por ningun lado. El casting es una indicación al compilador, así que para un programa genérico que usa tipos en tiempo de ejecución no sirve.

De todas formas, he estado mirando un poco y se ve que usar la clase Array no sirve, inexplicablemente, puesto que no se puede usar una instancia de Array donde se usaria un array ni hay metodo de conversión.... en fin. Peeeero, se puede arreglar usando List

Aquí un ejemplo de como crear un StringBuffer en tiempo de ejecución usando el constructor que recibe un String. El string se podría crear tambien de forma genérica con su constructor etc... pero lo he puesto "a pelo" para no complicar aun más el codigo, que ya es de por si bastante "interesante" .

Código:
    Class genericFinalClass = Class.forName("java.lang.StringBuffer");
    Class genericClass = Class.forName("java.lang.String");
    List contructorArgsList = new ArrayList(1);
    contructorArgsList.add(genericClass);
    Constructor genericConstructor = genericFinalClass
        .getConstructor((Class[]) contructorArgsList.toArray(new Class[]{}));

    // Aqui construyo el String a pelo, aunque se podría construir tambien
   // de forma generica.
    String testString = "Prueba prueba";
    List contructorObjsList = new ArrayList(1);
    contructorObjsList.add(testString);    
    Object genericInstance = genericConstructor.newInstance(contructorObjsList.toArray());
    System.err.println("genericInstance.getClass().getName(): " + genericInstance.getClass().getName());
    System.err.println("genericInstance.toString(): " + genericInstance.toString());
S!
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 15:22.