Se você simplesmente criou uma classe que extende ClassLoader
e não fez nada com ela, ela será só uma classe que não está sendo utilizada.
Para você utilizar um ClassLoader
criado por você, você precisa instanciá-lo como qualquer outro objeto e daí pode utilizá-lo para carregar suas classes que não estão no classpath da aplicação.
Ao usar a instrução new
você está invocando um construtor da classe, não carregando a classe em si. E sim, as classes instanciadas pela instrução new
, foram carregadas pelo Application ClassLoader
.
Para você instanciar uma classe que não está no classpath da aplicação, mas que o seu ClassLoader
customizado consegue carregar, você precisa utilizar reflection.
Basicamente fazer:
Class<?> classe = meuClassLoaderCustomizado.loadClass("nome binário de sua classe");
// daqui pra frente você usa reflection para instanciar a classe,
// se ela possui um construtor publico sem parâmetros,
// é só fazer o seguinte:
Object instancia = classe.newInstance();
// se possui construtor parametrizado,
// por exemplo que recebe uma String,
// precisa obter uma instancia do construtor desejado
Constructor construtor = classe.getDeclaredConstructor(String.class);
// e aí fazer assim:
Object instancia = construtor.newInstance("conteúdo da String");
Uma observação importante ´q que você não consegue declarar em seu código, classes carregadas dinamicamente.
Imagina que você usou seu ClassLoader
customizado para carregar uma classe chamada MinhaClasse
, você não poderá escrever um código assim:
// a linha abaixo está OK
Class<?> classe = meuClassLoaderCustomizado.loadClass("MinhaClasse");
// mas a linha abaixo está errada pois o compilador não conhece "MinhaClasse",
// daria erro em tempo de compilação
// MinhaClasse é uma classe dinâmica,
// que só é carregada em tempo de execução pelo seu ClassLoader customizado
MinhaClasse meuObjeto = classe.newInstance();
Como resolver essas situações?
Resposta: usando interfaces (ou classes abstratas, mas eu prefiro interfaces).
Se você criar uma interface na sua API e as classes que você carregar pelo seu ClassLoader customizado implementarem essa interface (ou extenderem a classe abstrata), você pode escrever seus códigos dessa forma:
Class<?> classe = meuClassLoaderCustomizado.loadClass("MinhaClasse");
MinhaInterface meuObjeto = classe.newInstance();