Ultimamente venho me perguntando sobre o funcionamento do Class.forName, em outras palavras o carregador de classes, que vc pode utlizar para carregar classes on-the-fly na sua app. Sempre programo, além de orientado a objeto, orientado a qualidade, segurança e perfomace que é de muitissima importância tb. Pois bem, tenho uma classe FactoryConnection em uma app que estou desenvolvendo, e q foi exigido que n se utlizasse o framework hibernate mas sim o padrão DAO, nessa FactoryConnection quando o usuário precisa realizar uma consulta, inserção , update etc no banco, ele deve ir a fabrica de conexoes acessar a propriedade estatica getConnection que irá entragar a ele uma conexão, e após a consulta o usuário deverá fechar esta conexão, todos os acessos ao banco é desta forma. Pois bem, esta propriedade getConnection utiliza o metodo Class.forName(“com.mysql.jdbc.Driver”) para carrega a classe DriverManager do mysql. Minha dúvida é a seguinte: Toda vez que usuário precisar acessar o BD será carregada a classe Driver em memória? Ou o metodo Class.forName checa primeiramente se já foi carregada esta classe em memória e só carrega a classe se não houver a classe em memória? Estou questionando ,pois, não gostaria de ver a app futuramente que deverá estar com constante uso e acessos, dando erro de outOffMemory permGen, que é área permanente da seguimentação de memória feita pela JVM onde comumente esta área esta reservada para alocação do byteCodes/classes e por objetos que persistiram as diversas execuções do GC(garbage collector) e à algoritmos de marcação e copia dos objetos em memória. Alguém sabe como funciona exatamente este metodo Class.forName?
Ao ler esse artigo http://www.javaworld.com/javaworld/jw-10-1996/jw-10-indepth.html eu entendo que a partir do primeiro carregamento não será mais necessário ter o overhead de carregar novamente a classe. Até porque se não fosse implementado dessa forma estaríamos diante de um problema grave de projeto da linguagem Java.
Acho que é carregado apenas uma vez e depois re-utilizada sem recarregamento.
Voce tem razao, nao havera segunda carregamento se voce estiver na mesma hierarquia de classloaders. Nesse topico ha a informacao que voce procura: http://guj.com.br/posts/list/12186.java
A rigor, o propósito de Class.forName é retornar um objeto do tipo java.lang.Class<?>.
Ele não "carrega" a classe; a classe é carregada (pelo classloader padrão se você usar a versão de forName com apenas 1 parâmetro, e pelo classloader passado como parâmetro se você usar a versão de forName com 3 parâmetros) apenas se ainda não houver sido carregada.
Se você tiver uma aplicação que cria N classloaders e chamar Class.forName (String name, boolean initialize, ClassLoader loader) para cada um desses classloaders, você terá N versões dessa classe carregadas (que não são iguais nem compatíveis entre si, embora tenham o mesmo nome).
Não é necessariamente assim Thingol(cara, adoro esse teu nick… me lembra que tenho que ler novamente o Silmarillion)
O contrato da classe ClassLoader diz, bem explicitamente, que todo ClassLoader deve primeiramente delegar ao seu classloader parent a carga da classe, e caso o parent(e os parents associados a este) não souber carregar, só então ele deve carregar. Se tivermos uma hierarquia de ClassLoaders, somente um ClassLoader terá o Driver carregado em memória.
Mas isto só é válido para ClassLoaders que sigam as regras do contrato da classe ClassLoader, e que possuam parents em comum, o que é o normal, mas sempre podem existir ClassLoaders rebeldes, que não aceitam os seus parents =P
[quote=leonardocoutoc]thingol,
Agora fiquei em dúvida se o meu metodo static estar criando vários classloaders, e carregando em cada um a classe DRIVER. [/quote]
Se você não está dando nenhum “new URLClassLoader” ou coisa parecida, seu código não deve criar vários classloaders, e você pode ficar despreocupado.