2010-12-08 32 views
15

Tengo una situación donde mi clase Java necesita crear una tonelada de cierto tipo de objetos. Me gustaría dar el nombre de la clase de los objetos que se crean como un parámetro. Además, necesito darle a la clase creada un parámetro en su constructor. Tengo algo así comoCreando una nueva instancia desde Clase con el parámetro constructor

class Compressor { 

    Class ccos; 

    public Compressor(Class ccos) { 
     this.ccos = ccos; 
    } 

    public int getCompressedSize(byte[] array) { 
     OutputStream os = new ByteArrayOutputStream(); 
     // the following doesn't work because ccos would need os as its constructor's parameter 
     OutputStream cos = (OutputStream) ccos.newInstance(); 
     // .. 
    } 
} 

¿Tiene alguna idea de cómo podría remediar esto?

Editar:

Esto es parte de un proyecto de investigación en el que necesitamos para evaluar el desempeño de múltiples compresores diferentes, con varias entradas diferentes. Class ccos es un archivo comprimido OutputStream de la biblioteca estándar de Java, Apache Compress Commons o lzma-java.

Actualmente tengo lo siguiente que parece funcionar bien. Otras ideas son bienvenidas.

OutputStream os = new ByteArrayOutputStream(); 
OutputStream compressedOut = (OutputStream) ccos.getConstructor(OutputStream.class).newInstance(os); 
final InputStream sourceIn = new ByteArrayInputStream(array); 
+0

¿Por qué necesita para decir 'Compressor' qué tipo de objetos para crear? ¿Qué clases de clases se usarán aquí? –

+1

¿Ha considerado utilizar una fábrica abstracta para esto en lugar de piratearlo con reflejos? –

+0

editado para agregar más información – lhahne

Respuesta

16

Puede usar el método Class.getConstructor(paramsTypes...) y llamar al newInstance(..) en el constructor. En su caso:

Compressor.class.getConstructor(Class.class).newInstance(Some.class); 
+1

Creo que te refieres a 'Compressor.class.getConstructor (Class.class) .newInstance (algún parámetro);' – lhahne

+1

@lhahne bien, ya que tu parámetro es del tipo 'Clase', puede ser' Some.class' – Bozho

+0

Ejemplo simple: CreateObjects es una clase java, puede invocar newInstance de la siguiente manera sin argumentos para el constructor. 'CreateObjects obj2 = CreateObjects.class.getConstructor(). NewInstance();' – srinivas

1

usted tiene que conseguir a la Constructor objeto relevante (por ejemplo a través de Class.getConstructors o Class.getConstructor) y luego llamar constructor.newInstance, dándole los argumentos que requiere.

-1
class Compresor<T> { 
    private Class<? extends T> clazz; 
    Compresor(final Class<? extends T> cls){ 
     this.clazz = cls 
    } 
} 
+0

eso no es lo que pregunté – lhahne

0

Un ejemplo que puede utilizar es la siguiente: digamos conn es una conexión con la base de datos.

Class[] btarray = { conn.getClass() };  
try{ 
if (classname != null) { 
pmap = (Mapper) Class.forName(
classname).getConstructor(btarray).newInstance(
new Object[] { conn }); 
} 
} catch (Throwable x) { 
    x.printStackTrace(Log.out); 
} 

btarray le permite pasar argumentos al constructor.

3

utilizando Spring ClassUtils y BeanUtils clases se pueden evitar hacer frente a esos tediosos excepciones que es la primavera de manipulación para usted:

Constructor<Car> constructor = ClassUtils.getConstructorIfAvailable(Wheels.class, Etc.class); 
Car car = BeanUtils.instantiateClass(constructor, new Wheels(), new Etc()); 
Cuestiones relacionadas