Dúvida sobre Class.forName("")

Boa tarde pessoal,

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?

att,
Leonardo Couto Conrado.

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.

Ola Leonardo!

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

E aqui tambem, no draft sobre classloaders do livro Arquitetura Java:
http://www.arquiteturajava.com.br/livro/entendendo...oderror-e-classloader-hell.pdf

Bom dia pessoal,

Muito obrigado pelas respostas era exatamente o q eu precisava fazer…

att,

Leonardo Couto Conrado.:spades:

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).

thingol,

Agora fiquei em dúvida se o meu metodo static estar criando vários classloaders, e carregando em cada um a classe DRIVER. Ele estar assim desta forma:

[code]public static Connection getConnection() throws SQLException {

	try{
		Class.forName(DRIVER_BD);
		connection = DriverManager.getConnection(URL_BD,USUARIO_BD,SENHA_BD);
		
	}

…[/code]

Será que será criado outro classloader a cada chamada deste metodo?

att,

Leonardo Couto.

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.