2011-03-29 8 views
9

He leído la documentación, pero todavía no entiendo qué cargador de clases debería proporcionar como argumento. He intentado algunas opciones, pero esto parece no tener ningún efecto en la compilación o el comportamiento del proxy. Es un poco inquietante que pueda pasar cualquier cosa como el argumento del cargador de clases, incluido el null, y el código sigue funcionando bien. ¿Alguien puede explicar esto y decirme qué tipo de errores pueden surgir si proporciono un argumento malo para el cargador de clases? Debo añadir que realmente no tengo una idea intuitiva fuerte de lo que es un cargador de clases, en Java o en general.¿Qué ClassLoader debería proporcionar a Proxy.newProxyInstance (...)?

Respuesta

6

Cualquier clase necesita tener un cargador de clases, por lo tanto, tenemos que dar una aquí.

La parte importante es esto (en the documentation for getProxyClass()):

Todos los tipos de interfaz debe ser visible por su nombre a través del cargador de clases especificado. En otras palabras, para cl cargador de clases y cada interfaz i, la expresión siguiente tiene que ser verdad:

Class.forName(i.getName(), false, cl) == i 

Por lo tanto, se puede utilizar cualquier cargador de clases, donde uno (o más) de sus cargadores de clases de padres definido los dados interfaces.

Si null funciona en su caso, supongo que sus interfaces tienen también el cargador de clase null (el cargador de arranque) - entonces no debería importar qué cargador de clases utilizó. Si tiene que crear un proxy de interfaces que no conoce, simplemente tome el cargador de clases de la primera interfaz dada y espere que su interlocutor no haya hecho algo extraño.

¿Por qué es necesario?

Se puede imaginar así:

  • El método getProxyClass() crea (si no existe todavía) un poco de código de bytes para una nueva clase que implementa todos los métodos de toda la interfaz (cada uno de ellos simplemente reenviar la llamada a su InvocationHandler).
  • Luego pasa este bytecode al método defineClass del cargador de clases que especificó.
  • En este bytecode, se hace referencia a todas sus interfaces por nombre, y la máquina virtual ahora usa la llamada citada forName para resolver estas interfaces.

Podríamos haber implementado este getProxyClass esta manera en Java puro, sin ningún tipo de magia VM, pero tendríamos que crear un nuevo cargador de clases (con el especificado como padre) para que en lugar de ser capaz de volver a utilizar una existente uno.

En realidad, puede que no haya un código de bytes real de esta clase sintética, ya que la máquina virtual es capaz de utilizar su magia interna aquí :-)

+0

Gracias, yo aún no tengo la intuición de lo que hace un cargador de clases . ¿Puedes mencionar un poco sobre esto? Todavía tengo dificultades para entender por qué un cargador de clases nulo podría funcionar si el cargador de clases fuera responsable de hacer algo sustantivo. ¿Tal vez un ejemplo de juguete en el que se da un cargador de clases incorrecto? – jonderry

+0

El cargador de clases 'null' es el" cargador de clases bootstrap ", el cargador de clases que carga las clases principales (como' Class', 'Object',' ClassLoader'). Se implementa de forma nativa por la máquina virtual y no tiene un objeto ClassLoader. (Es usado por 'Clase.forName' si le das 'null' como el argumento' ClassLoader', por ejemplo). (El ejemplo vendrá más tarde). –

Cuestiones relacionadas