 |
Página
17 - 1
Por que devemos ter cuidado com classes
que implementam o padrão de projeto
Singleton em aplicações J2EE?
Por que uma aplicação
J2EE possui diversos classloaders. Se a
classe Singleton tiver apenas métodos
de leitura, então tudo bem. Caso
contrário, você não
terá garantia de sempre estar alterando
o mesmo objeto.
Alem do que, em J2EE vc pode ter mais de
uma VM, mais de uma maquina, em mais de
uma rede... usando o pattern signleton mais
comum, que é, ter um método
estático que retorna a instância
atual, fica muito difícil controlar
tudo isto.
|
 |
Página
17 - 2
Por que clonar um objeto é mais
rápido que criar um novo?
Um objeto para poder ser clonado deve
implementar a interface java.lang.Cloneable
e ter o seguinte método:
public Object clone() {
try {
MinhaClasse
outra = (MinhaClasse) super.clone();
//Aqui
você incializa as suas propriedades.
return
outra ;
} catch (CloneNotSupportedException
e) {
return
null; // nunca chamado
}
}
Todas as propriedades primitivas ou imutáveis
como String são automáticamente
copiadas.
O método clone deverá inicilizar
apenas as propriedades mutáveis.
|
 |
Página
17 - 3
Como se descarrega uma classe em Java:
Como seria uma hierarquia de ClassLoaders
que possibilitasse isso?
ClassLoader é o responsável
pela carga de classes da JVM. Ele é
uma peça fundamental na implementação
de contêiners EJB e contêiners
Web, pois permite funcionalidades como
hot deploy (implantação
dinâmica de componentes). O Classloader
localiza os bytecodes de uma classe que
precisam ser carregados e cria uma instância
de java.lang.Class. Todas as classes referênciadas
pela classe carregada também serão
carregadas (classes são carregadas
no estilo /lazy-loading/, ou seja, carregadas
somente quando necessário).
O modelo de delegação de
ClassLoaders é constituido de um
ClassLoader raiz (conhecido como /bootstrap/
ClassLoader), um ClassLoader conhecido
como ClassLoader do sistema (/system/
ClassLoader, onde estão carregadas
todas as classes da API) e vários
ClassLoaders filhos (cada um carregando
classes de um repositório próprio)
constituindo uma estrutura
do tipo árvore.
O algorítmo de carga de classes
obedece os seguintes passos:
1. Quando é feita uma chamada a
uma classe, a JVM verifica se essa classe
já foi carregada, se sim a chamada
é executada e ponto final.
2. Se a classe requisitada não
foi carregada, a JVM solicita ao ClassLoader
da classe que está fazendo a
chamada para que essa carregue a classe,
se ele não conseguir, ele irá
delegar esse serviço para o seu
ClassLoader pai.
3. Se nenhum ClassLoader conseguir carregar
a classe, chegando assim ao ClassLoader
raiz (/bootstrap/ClassLoader), então
esse irá procurar em todos os arquivos
zip/jars encontrados nas seguintes
propriedades de sistema *sun.boot.class.path*
e *java.class.path*.
4. Se a classe não for achada então
a exceção java.lang.ClassNotFoundException
será lançada.
Pode-se implementar um ClassLoader proprietário.
Para isso, deve-se estender a classe java.lang.ClassLoader.
Como dito anteriormente, todo ClassLoader
deve possuir um pai. O método que
o cliente irá chamar para carregar
uma classe é o loadClass. Antes
do mecanismo de delegação
de ClassLoaders do Java 2, era necessário
sobreescrever esse método. Hoje,
deve-se apenas sobreescrever o método
findClass indicando ao ClassLoader a localização
do repositório que contém
a classe (o arquivo .jar por
exemplo). O método loadFromCustomRepository
é quem vai procurar o arquivo .class
no repositório e carregar os bytecodes
em memória. Esses bytecodes serão
passados para o método defineClass.
Este sim irá transformar os bytecodes
em uma instância de java.lang.Class.
Muitas aplicações não
podem parar para serem atualizadas. O
conceito de Hot Deployment consiste em
implantar, atualizar ou remover dinâmicamente
classes na aplicação. Um
ClassLoader não pode recarregar
uma classe. Mas uma nova instância
de ClassLoader pode ser criada para carregar
os novos componentes e tomar lugar do
ClassLoader antigo.
|
 |
Página
20 - 1
Qual é a forma mais simples
de se obter uma Data no formato dd/mm/aaaa
em Java?
SimpleDateFormat df = new SimpleDateFormat("dd/mm/yyyy");
String dataAtual = df.parse( new Date()
);
|
 |
Página
20 - 2
Qual é o princípio
que justifica que a seguinte expressão
"foo" == "foo" sempre
retorne verdade?
"string" == "string"
retorna verdade, pois não são
criado dois objetos "string"
diferentes em memória. A nova JVM
tem uma área de memória
para Strings, uma espécie de heap
para Strings.Ela pode usar o mesmo objeto
pra representar a String de mesmo valor.
|
 |
Página
31 - 1
Qual é a maneira mais
ágil de quebrar um String em várias
outras sem ter que recorrer aos métodos
subString?
Método split da jdk 1.4
|
 |
Página
31 - 2
Por que o seguinte código tende
a não funcionar bem?
Foo foo = new Foo();
ObjectOuput oos = ...
oos.writeObject(foo);
foo.setBar(bar);
oos.writeObject(foo);
Porque quando um objeto é serializado
a um ObjectOutputStream pela primeira
vez, todos os dados que ele possui são
gravados no stream, e o objeto ganha uma
identificação. Quando ele
é gravado novamente, mesmo que
seu estado interno tenha sido alterado,
o mecanismo de serialização
grava apenas o identificador. Ao ler o
objeto novamente mais tarde, vai parecer
que a chamada a setBar() nunca aconteceu.
Clique aqui
para saber mais
|
 |
Página
39 - 1
Qual a forma mais simples de
ler um arquivo texto localizado no CLASSPATH?
Class.getResourceAsStream("");
Reader reader = new BufferedReader(new
InputStreamReader(
this.class.getResourceAsStream("arquivo.txt")));
|
 |
Página
39 - 2
Qual é a principal diferença
entre Statement e PreparedStatement?
No preparedStatement existe uma verificação
do conetudo do statement.
Os PreparedStatements permitem que o código
SQL a ser executado possa ser pré-compilado
pelo banco de dados antes de executar.
Outra diferença importante é
que os PreparedStatements permitem a configuração
de parâmetros:
PreparedStatement pstmt = conn.prepareStatement("SELECT
* FROM foo WHERE bar = ?");
pstmt.setString(1, "baz");
|