Ir para o conteúdo

Instanciar Objectos com Ficheiros .class

De quando a quando, surge a necessidade de instanciar um conjunto de objectos para os quais não temos o nome, não conhecemos o tipo de construtor ou os parâmetros e para os quais temos apenas os ficheiros compilados, sem qualquer acesso ao código-fonte. Esta necessidade pode surgir de uma implementação de um sistema de plugins ou de qualquer outra situação onde pretendemos usar código que é adicionado depois da aplicação estar compilada, tipicamente pelo utilizador da aplicação.

No exemplo seguinte encontra-se uma forma possível de instanciar estas classes, com a única restrição de necessitarmos de uma interface comum, isto é, todas as classes presentes terão de ser subclasses de uma classe nossa conhecida ou implementar uma interface nossa conhecida. Esta limitação poderá ser removida se necessário dado que obtemos sempre a instância, com ou sem o uso da interface.

String baseFolder; //<- Usar para colocar o caminho para a pasta. Neste exemplo não foi preenchido.

Class tClass = null;
Reader reader = null; //<- nossa interface marcadora.
boolean found = false;

try {
    if (baseFolder != null) {
        File f = new File(baseFolder);
        if (f.exists() && f.isDirectory()) {
            URLClassLoader ucl = new URLClassLoader(new URL[]{f.toURI().toURL()}, ClassLoader.getSystemClassLoader());
            File[] flst = f.listFiles();
            String[] existing = null;
            if (flst != null) {
                existing = new String[flst.length];
                for (int z = flst.length; z-- > 0;) {
                if (findExtension(flst[z].getName()).equals("class")) {
                     existing[z] = stripFileExtension(flst[z].getName());
                     found = true;
                }
            }
        }

        if (found) {
            for (int z = existing.length; z-- > 0;) {
                //Instanciar a classe com base no nome
                tClass = Class.forName(existing[z], true, ucl);
                //Converter para a interface comum
                reader = (Reader) tClass.newInstance();
                //fazer o que pretendermos com a instância
            }
        }
    }           
} catch (MalformedURLException ex) {
    //tratar excepção
} catch (ClassNotFoundException ex) {
    //tratar excepção
} catch (InstantiationException ex) {
    //tratar excepção
} catch (IllegalAccessException ex) {
    //tratar excepção
}

Este exemplo faz uso dos métodos findExtension e stripFileExtension apresentados no snippet fileutils.