Mostrando postagens com marcador Java. Mostrar todas as postagens
Mostrando postagens com marcador Java. Mostrar todas as postagens

sábado, 26 de novembro de 2011

Queima de Livros de Computação

Fala galera! Irei me mudar ano que vem, e recebi um ultimato da minha esposa para me 'livrar' de algumas coisas que eu tenho, ela disse que na casa nova só quer coisa nova :(
Assim, estou vendendo os Livros abaixo (depois irei anunciar outras coisas), se alguém se interessar favor entrar em contato comigo pelo meu email ou deixa um comentário aí no post! Valeu!

Rails 3 Programming (R$ 45,00)                                                        Ruby Programming (R$ 50,00)


Core J2ME (R$ 20,00)                                                                          Hibernate em Ação (20,00)

Projetos Práticos com Jboss Seam (R$ 30,00)                               Hackers Expostos 4ed (R$ 50,00)

Sistema de Banco de Dados (R$ 60,00)                                     Criando Páginas com css (R$ 35,00) 

Effective Java - autografado pelo autor do livro (R$ 80,00)
Se alguém se interessar pelo bolo todo, fala aí que eu posso ver um desconto. Quanto à entrega, eu moro em Fortaleza, então é bom que você more por aqui também, pois não tenho ideia de quanto seria o frete pra outro lugar :) Abraço a todos!

quarta-feira, 3 de agosto de 2011

Novidades da JDBC 4

Quem nunca precisou fazer uma conexão JDBC em Java que atire a primeira pedra! Apesar de hoje em dia não ser comum utilizar JDBC puro em grandes projetos, embora haja quem o faça, a API continua evoluindo junto com a especificação do JSE.
A nova API, JDBC 4, foi incorporada ao JDK 6 e traz algumas mudanças como: melhor gerenciamento de objetos e suporte a novos tipos de dados, além das já existentes flexibilidade e facilidade de uso.
Uma mudança que a nova versão trouxe é na hora de obtermos uma conexão com o banco. Antes era necessário carregar a classe do driver JDBC antes de chamar o getConnection de DriverManager, por exemplo:

Class.forName("com.mysql.jdbc.Driver");
//Chamada ao DriverManager aqui

Esta chamada não é mais necessária, pois o próprio DriverManager se encarregará de localizar e carregar  a classe do Driver JDBC, para isto, basta que nós adicionemos o .jar no classpath da aplicação.
Outra novidade é o suporte a tipos de dados em XML, que estão definidos na SQL2003. O objeto é o java.sql.SQLXML, podemos fazer por exemplo:

SQLXML xml = Connection.createSQLXML( );

ou ainda:

SQLXML xml = resultSet.getSQLXML( );
InputStream is = xml.getBinaryStream( );

Seu uso é similar aos dos tipos CLOB e BLOB, que são suportados desde à versão 2.0, a nova versão traz  também a classe RowId, que permite fazer o acesso a um registro de forma mais rápida.
Agora é possível executar funções escalares como:
  • CHAR_LENTH, CHARACTER_LENGTH
  • CURRENT_TIME, CURRENT_DATE

Com o advento dos frameworks de ORM, como Hibernate, JPA, ficou cada vez mais raro usar JDBC, talvez você leitor nem mesmo soubesse que a API estava na versão 4.0, to mentindo? :) Mas eu acredito que é bom estudar as bases, pois se soubermos utilizar bem JDBC será mais fácil aprender a usar ORM, assim como o estudo de Servlets/JSP é importante para o aprendizado de frameworks web como JSF, Struts, Vraptor etc. Especialmente quando precisamos desenvolver alguns projetos de pequeno porte, onde não é necessário utilizarmos esses frameworks de grande porte. Espero que tenham gostado do post! Até o próximo post então!

terça-feira, 2 de agosto de 2011

Servlet Listeners - Listeners de Sessão - Parte 1

Olá Javeiros! Continuando a nossa sequência de posts sobre listeners (aqui tá o primeiro e aqui o segundo) hoje vamos começar a falar sobres os listeners de eventos de sessão. Vamos dividir o assunto em duas partes pois nós temos 4 interfaces para os listeners de sessão.

Antes de mais nada é importante que você saiba o que é uma sessão. Como o foco do post não é esse, não espere nenhum compêndio sobre o assunto aqui, quero apenas lembrar o conceito para aqueles que já viram algo sobre isso. Você nunca estudou o que é uma sessão http? Então é melhor você clicar aqui e dar uma estudada primeiro.

O protocolo HTTP é considerado um protocolo stateless, isso significa que cada requisição que é feita ao servidor é sempre uma novidade. Lembra do filme "Como se fosse a primeira vez"? Pois é, depois que o servidor recebe a requisição e envia a resposta ele jamais lembrará o que tinha nessa requisição. Bom, mas isso é porcaria não? É, realmente seria se não fosse o conceito de sessão http. Uma sessão http nada mais é do que a identificação das requisições de um usuário, como o protocolo http não armazena o estado das requisições, os  clientes enviam algo nela para que servidor saiba que aquela requisição foi feita pelo usuário A e não pelo B. Essa informação é o session ID.

Existem basicamente duas maneiras de implementar o controle de Sessão em uma aplicação Web Java:  através de Cookies ou da reescrita de URLs. A API de Servlets suporta as duas formas e o melhor é que o processo de controle é totalmente automático para o desenvolvedor. Cookies podem ser desabilitados pelo cliente, sendo assim, quando não for possível utilizar esta técnica, os Servlets poderão reescrever as URLs adicionando a elas o nosso Session ID.

A criação de uma Sessão pode ser feita a partir da chamada ao método getSession. Este método retornará a sessão que está associada à requisição atual, caso não exista, uma Sessão nova é criada. Você pode passar um booleano como parâmetro caso deseje decidir criar ou não uma nova sessão.

HttpSession session = request.getSession( ); 

Depois que um sessão é criada, toda requisição feita entre cliente e servidor carregará o session ID. A partir daí precisamos definir o tempo de duração de uma sessão e quando destruí-la, já que não há como saber se o cliente não está mais 'ativo'.

Encerrando uma Sessão

Existem duas formas de encerrar uma sessão, através da definição de um tempo máximo de inatividade setMaxInactiveInterval ou através da chamada ao método invalidate, os dois métodos estão presentes na interface HttpSession. É possível também configurar o tempo máximo através de um parâmetro no arquivo web.xml da aplicação, conforme pode ser visto abaixo:

 <session-config>
   <session-timeout>30</session-timeout>
 </session-config>

Vale apenas ressaltar que o tempo definido através do método setMaxInactiveInterval é em segundos, enquanto no web.xml é em minutos.


HttpSessionListener


A API de Servlets permite que interceptemos o momento em que uma sessão é criada ou destruída. Para isso precisamos criar um Listener de Sessão através da implementação da interface javax.servlet.http.HttpSessionListener. Essa interface possui 2 métodos que serão chamados sempre que uma sessão for criada, sessionCreated, ou destruída, sessionDestroyed. Por último a classe precisa ser configurada no web.xml para que o container possa chamá-la. A API 3.0 de Servlets permite a utilização de annotations na classe Listener, eliminando a necessidade do mapeamento no web.xml.
A seguir temos um exemplo de uma classe que implementa HttpSessionListener utilizando anotações.




Caso você não esteja usando a nova versão de Servlets, você deve mapear o listener no arquivo web.xml da aplicação:

 <listener>
   <listener-class>30</listener-class>
 </listener>


No próximo artigo iremos falar sobre sobre os outros Listeners de Sessão (Activation, Binding e Attribute).
Até o próximo post!

quarta-feira, 30 de junho de 2010

Tomcat 7 foi lançado! Vejas as novidades.

 A apache lançou oficialmente a versão 7 do tomcat, que recentemente completou 10 anos de criação, o que faz dele um projeto bastante maduro, apesar de apenas 7 versões. No mundo open source é comum não termos milhares de versões, afinal de contas esse negócio de mil versões tem um apelo meramente comercial.
Vale a pena conferir a nova versão, que já oferece suporte à especificação de servlets 3.0 e jsp 2.2. Veja aqui tudo que mudou nessa versão e se quiser degustar a versão é só fazer o download aqui.

sábado, 15 de maio de 2010

Servlet API: Utilizando parâmetros de incialização

Olá Javeiros! Dando continuidade ao nosso estudo para a certificação SCWCD veremos neste post rápido como fazer para utilizar parâmetros de inicialização em nossa aplicação e também em um Servlet específico.

É possível adicionar parâmetros que são acessíveis por toda a aplicação. Muitos frameworks web fazem uso desse recurso. Digamos que a aplicação necessite enviar um email para o administrador reportando erros, se colocarmos o email do administrador no código da aplicação e este email sofra alguma mudança, será necessário gerar um novo arquivo de deploy da aplicação. Este problema pode ser resolvido adicionando um parâmetro de inicialização no arquivo descritor (web.xml), e dessa forma ele estará disponível para toda a aplicação.

Digite o trecho a seguir entre as tags web-app do seu arquivo descritor. 


A API de Servlet disponibiliza, através da interface ServletContext, métodos para acessar os parâmetros de inicialização. Existem dois métodos para tal:

  • Enumeration getInitParameterNames: Este método retorna uma enumeration contendo todos os nomes de parâmetros disponíveis no web.xml. Ele é muito útil quando não se sabe o nome do parâmetro.
  • String getInitParameter(String name): Este método retorna o valor (param-value) do parâmetro de inicialização. Vale lembrar que sempre é retornado uma String e nunca outro tipo como Integer, Long, etc.
No trecho de código abaixo podemos ver o uso desses métodos a partir de um servlet.


Quando o servlet for acessado ele irá exibir todos os parâmetros de inicialização disponíveis.
É possível também criar parâmetros de inicialização para Servlets, a diferença é que estes serão visíveis somente para os servlets onde foram declarados. O conceito é basicamente igual ao anterior, porém devemos atentar para as tags que criam cada um deles. No exemplo anterior nós colocamos a tag context-param na raiz do nosso descritor, já para os parâmetros de servlets iremos utilizar a tag init-param e esta deve ser declarada sobre a tag servlet (tag de declaração de um servlet).

O trecho abaixo mostra a criação de um parâmetro para um Servlet.









Veja que a única diferença para o exemplo anterior é a tag init-param. Outra mudança também é na forma como o parâmetro é acessado. Na verdade a mudança é no objeto em que ela é acessado, não mais o ServletContext e sim o próprio Servlet.

Vejamos abaixo o código que acessa os parâmetros do servlet:












Observe que o método getInitiParameterNames é chamado diretamente de Servlet e não mais do contexto como no exemplo anterior.

Então é isso pessoal. Espero que tenham gostado do post! Até o próximo então.

domingo, 2 de maio de 2010

Criando funções JSP com EL

Galera, pra quem vai tirar (ou não) a certificação SCWCD 5.0, um dos objetivos do exame é saber se o candidato sabe criar funções com EL (Expression Language) para serem usadas em suas páginas JSP. A criação de funções EL serve para que você pense duas vezes antes de usar os malditos scriptlets em suas páginas JSP (sério, não faça isso por favor).
O processo envolve basicamente quatro passos:
  1. Criação de uma classe Java que conterá os métodos que você irá utilizar nas suas páginas JSPs.
  2. Criação do arquivo tld (Tag library descriptor) que conterá o mapeamento entre o método Java e sua versão XML.
  3. Mapeamento da sua tld no web.xml (isso é opcional... mas é legal utilizar)
  4. Declaração da taglib na sua página JSP.
Vamos criar um exemplo simples para explorar os passos acima. Criaremos uma função que calcula a raiz quadrada de um número. Mãos à obra.

Passo 1: Vamos criar uma classe chamada functions.MyMath e nela vamos criar um método square que será responsável pelo cálculo da raiz quadrada. Precisamos de alguns cuidados neste momento. A especificação diz que esta classe deve ser pública e os métodos que serão acessados pelas páginas JSPs devem ser públicos e estáticos. Dito isto, vejamos como ficou a nossa classe:

Passo 2: Vamo criar o arquivo tld. Este arquivo permitirá o mapeamento entre o nosso método java uma função XML que a EL possa executar (EL não permite a invocação de métodos Java). Uma observação importante é que caso o arquivo tld esteja sobre o diretório WEB-INF da sua aplicação ele é automaticamente reconhecido por ela, caso esteja em outro lugar você terá que fazer o passo seguinte.

Eu odeio quando as coisas não seguem um padrão nesses malditos arquivos xml... deixando a ira de lado, notem que o atributo que mapeia o nome da função não é function-name (o que faria muito mais sentido) e sim name, ele será usado para chamar de fato o nosso método java, você não precisa colocar o mesmo nome do método, mas fica melhor dessa forma. Outras dicas importantes são que em function-class deve ser colocado o nome completo da classe (com o pacote, conhecido como full qualified name) e em function-signature os tipos do retorno e da entrada devem ser também completos. Você pode usar todos os tipos básicos de Java e incluindo os wrappers sem necessidade de importação nas páginas JSP, caso não seja um desses tipos você terá que fazer a importação.

Passo 3: Este passo é opcional caso o seu arquivo tld esteja sobre o diretório /WEB-INF da aplicação, mas eu recomendo fortemente que você o faça. Por quê? Bem, digamos que um belo dia você resolve mover ou mudar o nome do arquivo... imagine só ter que sair alterando todas as páginas JSPs que fazem uso do arquivo... chato né? Então largue a preguiça de lado e coloque o conteúdo abaixo no arquivo web.xml:


Passo 4: Por fim precisamos declarar nossa função na página na qual desejamos chamá-la. O processo é bastante simples, principalmente se você já tiver utilizado JSTL. Vejamos como fica a nossa página JSP:


Se você fez tudo direitinho, ao executar a página acima será exibida a mensagem "A raiz quadrada de 25 é 5.0". Uma última coisa a dizer é sobre o argumento uri, apesar de ele está no formato absoluto (com protocolo etc) isto não significa que a JSP irá tentar acessar este endereço, apenas ela irá procurar no descritor (web.xml) se alguma taglib declarada ali combina com esta uri informada).

Bom galera, isso é tudo! Espero que tenham gostado da dica e até o próximo post!

domingo, 8 de novembro de 2009

Dica 3: Descompactando Arquivos Zip

Essa dica é baseada nos exemplos do deste artigo da sun. Lá você pode conferir outros exemplos em inglês. Não é algo comum, mas certamente muitas pessoas já precisaram descompactar um arquivo zipado em uma aplicação. Essa tarefa tornou-se mais fácil depois que o Java disponibilizou as classes do pacote java.util.zip.*. A leitura do arquivo zip é simples. Utilizamos a API de I/O do Java. Precisamos de um Buffer para leitura e um para escrita e também das classes ZipFile, que encapsula o arquivo Zip e a classe ZipEntry que encapsula um arquivo dentro do zip. A classe ZipFile fornece um método que retorna os arquivos que estão contidos dentro do zip, basta percorremos o enum e ler cada um dos arquivos. É possível ainda saber se o 'arquivo' que estamos lendo é um diretório através do método isDirectory, caso contrário deve ser utilizada uma outra abordagem (não mostramos aqui), com o Stream podemos então escrever os arquivos fora do zip.
Na imagem abaixo temos o código fonte de exemplo.


Até a próxima dica!

segunda-feira, 2 de novembro de 2009

Dica 2: Escrevendo em um arquivo com Java

Na dica 1 vimos como fazer pra ler um arquivo utilizando Java. Nesta dica veremos como escrever conteúdo em um arquivo.
O processo de escrita em arquivos é muito semelhante ao de leitura, basicamente as classes/interfaces que antes terminavam com Reader agora terminam com Writer. O uso buffer é opcional para o caso de escrita, pois a classe FileWriter fornece método para escrita de strings diretamente no arquivo (a classe FileReader só permite leitura em bytes).
O código abaixo mostra como escrever em um arquivo em Java.



É isso aí pessoal! Até a próxima dica.

domingo, 1 de novembro de 2009

Dica 1: Lendo Arquivo com Java

Salve javeiros de plantão! Depois de um tempão fora do ar por causa dos estudos, vamos voltando aos poucos a postar no javeiro.
Irei começar uma série de dicas rápidas em Java, ideal para aqueles que não querem perder tempo lendo um monte de coisa :D.
A primeira dica é como ler um arquivo em Java. A API de I/O do Java é bastante rica e também um pouco chatinha de trabalhar, são muitas classes que se combinam para executar tarefas. A cada versão nova do Java temos vista diversas melhorias nessas APIs.
O código abaixo mostra como fazer a leitura de um arquivo em Java.


Essa é uma das formas de ler um arquivo em Java. Espero ter ajudado. Até a próxima dica!

sábado, 29 de novembro de 2008

Operadores e Atribuições - Tabela de Precedência

Olá javeiros! Após um período longe do blog (estou estudando pra dois concursos e pra prova SCWCD) vamos tentar aos poucos voltar a escrever algum post no nosso blog. Assim que essa fase passar prometo que vou postar mais coisas aqui. Então vamos voltar ao Java!
Neste post vamos começar a estudar os operadores e atribuições em Java. Operadores são essenciais em uma linguagem de programação, e normalmente eles são semelhantes em todas as linguagens. Antes de vermos cada um deles, precisamos saber a precedência dos operadores. A precedência é importante quando temos uma expressão para ser executada. O resultado da expressão vai depender da precedência dos operadores. Veja na tabela abaixo a precedência dos operadores na linguagem Java:

OperadoresPrecedência
postfix
expr++ expr--
unário
++expr --expr +expr -expr ~ !
multiplicativo* / %
aditivo+ -
deslocamento<< >> >>>
relacional< > <= >= instanceof
igualdade== !=
bitwise AND&
bitwise exclusive OR^
bitwise inclusive OR|
lógico AND&&
lógico OR||
ternário
? :
atribuição= += -= *= /= %= &= ^= |= <<= >>= >>>=

Essa tabela embora pareça muito grande, na verdade é muito intuitiva. A maioria de nós já aprendeu pelo menos a precedência dos operadores matemáticos, que são maioria na tabela. No próximo post vamos estudar a maioria desses operadores. Não vamos estudar todos por que alguns foram retirados do exame 5.0 (ainda bem). Até o próximo post então!

sábado, 27 de setembro de 2008

Agora eu sou SCJP!!

Quero pedir desculpas pela minha ociosidade repentina mas é que eu estava na minha semana decisiva. Fiz a prova da certificação ontem e obtive 83% \o/. Acertei 60 das 72 questões, um resultado além do meu esperado. A prova estava bem tranquila mas é lógico que eu estudei pra caramba pra fazer. Então em breve estaremos postando novos artigos sobre a SCJP, agora que estou mais experiente vai ficar ainda melhor. um abraço e até o próximo post.

quarta-feira, 3 de setembro de 2008

Novidades do Java 5.0: Enums

Hoje iremos aprender mais um assunto novo para a prova de certificação java 5.0: os enums. Podemos entender enums como tipos de constantes. Por exemplo: SEGUNDA, TERCA, QUARTA...etc, podem ser iplementados como constantes ou membros de um enum chamado DiasDaSemana. Enums ajudam bastante os programadores a tornar seus códigos mais claros e com menos possibilidades de bugs.
Para definir um enum usamos a palavra chave enum, por exemplo, o nosso enum descrito acima ficaria assim:

public enum DiasDaSemana {
DOMINGO, SEGUNDA, TERCA, QUARTA, QUINTA,
SEXTA, SABADO
}


Um enum pode ser declarado em uma classe própria ou ainda dentro de uma classe. Vejamos como é isso:

enum DiasDaSemana {
DOMINGO, SEGUNDA, TERCA, QUARTA, QUINTA,
SEXTA, SABADO
}

class Calendario {
enum Meses {
JANEIRO, FEVEREIRO, MARCO
//OUTROS MESES AQUI
}
DiasDaSemana dia;
Meses mes;
}

public class UsandoCalendario {

public static void main(String... args){
Calendario c = new Calendario();
c.dia = DiasDaSemana.SEGUNDA;
c.mes = Calendario.Meses.JANEIRO;
}
}

Apesar de enum ser um classe (é isso mesmo) um enum não é instanciado diretamente como as outras classes em java (usando new por exemplo), basta chamar uma de suas 'constantes'. A ordem dos elementos de um enum é importante e uma coisa importante também é que nada pode ser declarado antes delas. Bom, você pode declarar variáveis em um enum, mas elas precisam vir após a declaração dos elementos. Por exemplo:

enum DiasDaSemana {
private boolean diaUtil; // erro!
DOMINGO, SEGUNDA, TERCA, QUARTA, QUINTA,
SEXTA, SABADO
}

O correto seria:

enum DiasDaSemana {
DOMINGO, SEGUNDA, TERCA, QUARTA, QUINTA,
SEXTA, SABADO; // o ; é obrigatório caso declare algo depois

private boolean diaUtil;
}


Enums também pode ter construtores. Porém eles não são acessíveis fora da definição do enum. Podemos usar os construtores para inicializar algum tipo de variável ou valor default para um enum. Por exemplo:

enum DiasDaSemana {
DOMINGO(false), SEGUNDA(true), TERCA(true), QUARTA(true), QUINTA(true), SEXTA(true), SABADO(false);
// o ; é obrigatório caso declare algo depois

private boolean diaUtil;

DiasDaSemana(boolean util){
this.diaUtil = util;
}

public boolean isDiaUtil(){
return this.diaUtil;
}

Enums também pode ser utilizados com a estrutura de switch. Como no exemplo abaixo:

public enum Luas {
CHEIA, CRESCENTE, MINGUANTE, NOVA
}

.... definição da classe
Luas l = Luas.NOVA;
switch(l) {
case CHEIA: //codigo aqui
case CRESCENTE: //codigo aqui
case MINGUANTE: //codigo aqui
case NOVA: //codigo aqui
default: //codigo aqui
}

Até o próximo post.

terça-feira, 2 de setembro de 2008

Novidades do Java 5.0: Varargs

Suponhamos que você deseja criar um método que faz a soma dos inteiros passados como parâmetros nele. Como você faria isso antes do java 5? Bem, teríamos que fazer algo do tipo:

public int somar(int a) {
return a;
}

public int somar(int a, int b) {
return a + b;
}

public int somar(int a, int b, int c){
return somar(a,b) + c;
}
...

O problema é que para conseguir suportar mais argumentos você teria que criar mais métodos sobrecarregados, tornando a sua classe gigante e difícil de manter. A partir do java 5 ficou muito mais fácil criar essa funcionalidade. Através da sintaxe de argumentos variáveis ou varargs. Então os métodos que nós escrevemos antes ficariam todos resumidos em um método assim:

public int somar(int... args) {
int total = 0;
for (int i = 0; i < args.lenght; i++)
total += args[i];
return total;
}

chamadas válidas ao método
System.out.println(somar()); imprime 0
System.out.println(somar(1)); imprime 1
System.out.println(somar(1,2)); imprime 3
System.out.println(somar(1,2,3)); imprime 6

Acho que você notou que o argumento variável nada mais é que um array de objetos ou de primitivos do tipo informado no parâmetro né? Só que o recurso é mais interessante porque me dá a flexibilidade de passar quantos parâmetros eu quiser sem precisar declará-los em um array. Agora vejamos as regras do varargs:
  1. Todo vararg tem um tipo definido. Como no nosso exemplo o tipo foi int.
  2. Para definir que o parâmetro é vararg use ... (três pontinhos) depois do tipo. Cuidado para não confundir com a sintaxe de arrays, ainda não vimos arrays mas vamos adiantar a sintaxe aqui: um array pode ser definido: int[] a ou int a[]. Um vararg só pode ser int... a e NUNCA int a...
  3. Eu posso ter vários parâmetros junto com o vararg, porém só posso ter um ÚNICO vararg como parâmetro e este precisa ser OBRIGATORIAMENTE o último deles. Assim é válido ter: public void somar(String msg, int... a); mas é inválido: public void somar(int... a , String msg);
Por último devemos saber que acessamos vararg como se tivéssemos acessando um array do tipo informado. Assim você pode usar qualquer estrutura de laço ou índice, como for por exemplo.
Até o próximo post.

Declarando Variáveis de Classe

No post anterior vimos como declarar variáveis locais. Vimos que normalmente o escopo de uma variável local é o método ou a estrutura onde ela foi declarada (por ex. um for) e vimos ainda que elas só aceitam o modificador final.
Agora iremos aprender o que são e como usar variáveis de classe. Uma variável de classe nada mais é do que uma variável que tem o seu escopo na classe na qual ela foi criada. Isso quer dizer que ela vive enquanto a classe estiver viva (ou na memória né...). Você define uma variável como sendo de classe utilizando o modificador static. Uma variável estática pode ser acessada diretamente através da classe, ou seja, eu não preciso ter um objeto (ou uma instância de um) para acessar a variável, só preciso utilizar ClassName.variableName. Vamos dar um exemplo:


public class Carro {
public static String cor = "Azul";
}

public class TesteCarro {
public static void main(String args[]){
Carro c = new Carro();
System.out.println(Carro.cor); //classe
System.out.println(c.cor); //objeto
}
}
Note que não criamos um objeto Carro, simplesmente chamamos a variável cor através da classe Carro (claro que isso foi possível também porque cor é uma variável pública). Você pode também acessar uma variável de classe através de uma instância da classe, pois todas as instâncias compartilharão a mesma variável, já que ela pertence à classe. Então eu sugiro que você sempre acesse via classe mesmo e não via objeto, até para deixar seu código mais claro.
Até o próximo post.

sábado, 30 de agosto de 2008

O que aprendemos até aqui

Vamos dar uma paradinha rápida no estudos para vermos o que aprendemos até aqui. Como já havia falado antes, estamos seguindo o conteúdo completo (não sei se vamos conseguir mostrar tudo, mas tentaremos) do programa de certificação para programador. Até aqui só vimos o objetivos da seção 1 (quero ver essas seções):
Section 1: Declarations, Initialization and Scoping
1.1 - Aprendemos a declarar classes concretas e abstratas. Ainda falta vermos enum.
1.2 - Aprendemos a declarar interfaces e implemtá-las, vimos que seus métodos são todos públicos e abstratos, e que todos as variáveis são constantes (public static final).
1.3 - Só vimos os identificadores válidos lembra (começa com $,_, ou letra, depois qualquer outro caractere unicode)
1.4 - nada visto ainda.
1.5 - nada visto ainda.
1.6 - nada visto ainda.

Já deu pra ver que falta muita coisa ainda né? Bom, alguns assuntos a gente vai ter que pular, mas só aquilo que a gente vir que dá pra você pegar de letra. Mas fique calmo, não vamos querer desistir por causa disso né? Uma dica para aqueles que não conseguem estudar (como eu :) ): marque a prova que você vai ser obrigado a estudar...rs é meio masoquismo, mas comigo funcionou.
Aguardem que vem mais post em breve. Até lá.

quarta-feira, 27 de agosto de 2008

Declarando membros de classes - Parte 2

No post anterior nós estudamos sobre membros públicos. Vimos que eles são acessíveis a partir de qualquer classe. Neste post iremos estudar sobre os níveis protected e default. Isso porque eles são muito parecidos. E você vai notar rapidamente a diferença entre eles.

O nível default pode ser entendido como um nível de acesso de pacotes. Isso quer dizer que se você declarar um membro como default (na verdade você não vai colocar o modificador, lembra?) somente as classes que estiverem dentro do mesmo pacote que a sua terão acesso ao membro. Vamos pegar o exemplo anterior e retirar o modificador das variáveis de instância:


Animal.java
//Classe public diz que todos vão enxergá-la
public class Animal {
//Membro (variável) default
//somente classes do mesmo pacote
//poderão acessar o membro.
String nome;
}

Gato.java

public class Gato extends Animal {
String raça;

public void mostrarNome(){
System.out.println(nome); //pode?
}

}

package javeiro;
Exercicio1.java
public class Exercicio1 {

public static void main(String arg[]){
Gato g = new Gato();
g.nome = "Garfield"; //e aqui?
g.raça = "preguiçoso"; //aqui também né?
}
}

O método mostrarNome numa primeira olhada parece fazer uma operação ilegal tentando exibir a variável nome, que é de Animal e está marcada como default. Porém não há problemas, pois as classes Animal e Gato estão no mesmo pacotes, isso significa que além de herdar os membros públicos, gato também herda os membros default, nós veremos mais adiante que é possível fazer uma classe herdar os membros default de uma classe que está em outro pacote. Já a classe Exercicio1 não será compilada com sucesso. O compilador irá dizer que não conhece a propriedade nome e muito menos raça do objeto gato. Por que isso acontence? Exatamente isso que você pensou, Exercicio1 está em um pacote diferente da classe Gato, e isso faz com ela possa acessar somente os membros públicos dela.

Membros protegidos (protected)

O nível protected é muito parecido com o nível default. A diferença básica é que os membros protegidos podem ser acessados por classes de pacotes diferentes, desde que estas sejam subclasses da sua classe. As outras regras são iguais, ou seja, os membros protegidos só podem ser acessados por classes que estão dentro do mesmo pacote (com a exceção que falamos antes). O exemplo que faremos irá elucidar as dúvidas que possam ter resistidos:


Animal.java
package javeiro.pacote1;
//Classe public diz que todos vão enxergá-la
public class Animal {
//Membro (variável) protected
//somente classes do mesmo pacote
//e subclasses poderão acessar o membro.
protected String nome;
}

Gato.java
package javeiro.pacote2;
import javeiro.pacote1.Animal;

public class Gato extends Animal {
protected String raça;

public void mostrarNome(){
System.out.println(nome); //herdou nome
}

}

package javeiro;
Exercicio1.java
public class Exercicio1 {

public static void main(String arg[]){
Gato g = new Gato();
g.nome = "Garfield"; //não pode
g.raça = "preguiçoso"; //não pode
}
}

Temos aqui algo muito parecido com a versão anterior onde tínhamos os membros default. A diferença pode ser nota na classe Gato, que faz um acesso ao membro nome mesmo este sendo protected (deveria ser acessado por classes do mesmo pacote), porém membros protected são acessíveis por classes de outros pacotes através de herança. Já a classe Exercicio1 não compilará, pois está tentando fazer acesso a duas variáveis protegidas de classes de outros pacotes (Animal e Gato).
Então não esqueça:
  • DEFAULT -> Permite acesso aos seus membros SOMENTE às classes do mesmo pacote.
  • PROTECTED -> Permite acesso aos seus membros às classes do mesmo pacote e às classes de outros pacotes através de HERANÇA.
Até o nosso próxim post!

segunda-feira, 25 de agosto de 2008

Declarando Interfaces

Saudações java a todos! Vamos continuar o nosso estudo para a certificação de programador java, agora com um assunto mais interessante: interfaces. Você já deve ter ouvido falar muito em interfaces né verdade? Provavelmente o termo: interface com o usuário. Bom, mas a interface que falaremos aqui é um pouco diferente, esta outra está relacionada normalmente com uma tela gráfica ou página web, a nossa tem a ver com herança e polimorfirsmo (vamos manter a sanidade).

Uma interface nada mais é que um contrato. Isso mesmo, não dá pra complicar, é simples mesmo. Um contrato possui clásulas que devem ser cumpridas por aqueles o assinaram. A diferença é que diferente dos contratos da vida real, os contratos das interfaces jamais poderão ser quebrados. Usando POO, uma interface define um comportamento que você deseja que determinadas classes tenham, por exemplo: Você possui um sistema de biblioteca, e você possui Objetos dos tipos Livro, Revistas, Cds, Dvds etc, mas estes objetos devem compartilhar uma característica como: poderem ser alugados. Como fazer isso usando o que há de melhor na POO? A resposta é: criando uma interface comum a todos esses objetos. Poderíamos ter uma interface nomeada como Alugavel, que deveria ser implementada por qualquer objeto da biblioteca que puder ser alugado. Aguente as pontas que em breve traremos um exemplo mais claro nesta seção.

As interfaces são simples porém poderosas. Quando bem utilizadas tornam o seu sistema muito mais claro e fácil de ser expandido. As interfaces, juntamente com as classes abstratas, permitem o uso do Polimorfismo, deixando o seu código claro e flexível.
Vimos que uma classe abstrata não pode ser instanciada e que todos os seus métodos abstratos deveriam ser implementados pela primeira classe concreta que a estendesse. Pois bem, uma interface é muito parecida com uma classe abstrata, com a diferença que a interface é totalmente abstrata, isso significa que você não poderá definir métodos concretos lá como numa classe abstrata. E não é só isso! Os contratos das interfaces são bem rígidos, vejamos algumas cláusulas deste contrato:

  1. TODOS os métodos de uma interface SÃO públicos e abstratos. Eles já nascem assim. E não há nada que você possa fazer para mudar isso. Mesmo que você não coloque os modificadores public e abstract, para o compilador java é como se eles estivessem lá. Então os dois métodos abaixo são perfeitamente válidos em uma interface e fazem o mesmo efeito:
    • public abstract void executar();
    • void executar();

  2. TODAS as variáveis de uma interface DEVEM ser públicas, estáticas e finais. Isso significa que uma interface só pode declarar constantes (e elas são bastante utilizadas para este fim).
  3. Você NÃO pode declarar método final em uma interface, pois eles são abstratos por padrão (ponto 1). Um método de interface também NÃO pode ser: static, native, strictfp e nem syncchronized.
  4. Interfaces PODEM fazer herança múltipla. Yes, man they can. Uma interface pode herdar de quantas outras interfaces ela quiser.
  5. Uma interface NÃO pode implementar outra interface e nem pode estender de nada que não seja interface.
  6. Você pode ou não utilizar o modificador abstract na declaração da interface. Já a palavra interface é obrigatória.

Esses cinco pontos são o que você precisa saber sobre interfaces. A seguir traremos alguns exemplos de uso das mesmas para fixarmos o conteúdo.

// abstract é opcional aqui
public abstract interface Alugavel {
//aqui é implicitamente public static final
int TEMPO_MAXIMO_ALUGUEL = 7; //É comum definirmos como constantes

//aqui é implicitamente public abstract
void alugar(); // não tem '{'
}

//utiliza a palavra implements para implementar a interface
public class Livro implements Alugavel {
//precisa ser implementado e publico
public void alugar() {
//regras de negócio aqui
}
}

Em uma outra oportunidade falaremos um pouco sobre o Polimorfismo. Por enquanto isso é tudo o que você precisa saber sobre interface para se dar bem na prova.

Até o próximo post.

Identificadores e Palavras Reservadas

Este tópico é bastante simples porém é fruto de muitas pegadinhas na hora da prova. E pode apostar que a prova vai estar cheia delas. Então para evitarmos perder questões bobas vamos aprender neste post como declarar identificadores, que nada mais são que os nomes de nossas variáveis, métodos e classes.
As regras de nomenclatura dos identificadores em java são muito parecidas com as de outras linguagens como delphi, c, c++ etc. Antes de listarmos as regras é preciso saber que o java utiliza a codificação Unicode para os arquivos de código fonte. As regras são as seguintes:
  • Os identificadores DEVEM começar com uma letra, um cifrão ($) ou com um underscore (_).
  • Após o primeiro caractere pode ser usado qualquer outro caractere do conjunto Unicode.
  • NÃO se pode usar uma palavra reservada (vamos já saber o que é isso) como identificador.
  • Em java, os identificadores são case sensitive. Então você pode definir gato e Gato como duas coisas diferentes;
Para fixar os conceitos, abaixo está uma lista contendo identificadores válidos:
  • int _var;
  • double ist0_é_válido; //não recomendo, mas é válido
  • float R$100; //legal né? :)
  • int ________________Legal;
Palavras reservadas da linguagem Java:
abstract continue for new switch
assert*** default goto* package synchronized
boolean do if private this
break double implements protected throw
byte else import public throws
case enum**** instanceof return transient
catch extends int short try
char final interface static void
class finally long strictfp** volatile
const* float native super while
*
Não utilizada
**
Adicionada em 1.2
***
Adicionada 1.4
****
Adicionada 5.0
Ao todo são 50 palavras reservadas. A má notícia é que você terá que saber todas elas, então utilize a sua técnica de memorização preferida e boa sorte... Mas você verá que não é tão difícil assim quanto parece. Especialmente se você já trabalha com java ou está sendo obrigado a fazer isso (faculdade por exemplo). Para ajudar você a memorizar vamos fazer uma pequena divisão:
De quebra já devemos saber os tipos primitivos, são 8:
  • boolean, byte, char, double, float, int, long, short.
Utilizadas em definição de classes e métodos, são 15:
  • abstract, class, enum, final, interface, native, private, protected, public, static, strictfp, synchronized, transient, void, volatile.
Utilizadas em laços e retornos de métodos, são 9:
  • break, case, continue, default, do, for, return, switch, while.
Utilizadas em tratamentos de exceção, são 5:
  • catch, finally, throw, throws, try.
Estruturas condicionais e verificações, são 3:
  • if, else, instanceof.
Usadas em herança, são 2:
  • extends, super.
Importação e definição de pacote, são 2:
  • import, package.
NÃO SÃO UTILIZADAS, são 2:
  • goto, const.
Adicionadas recentemente, são 2:
  • assert, enum;
Criação de objetos e acesso à classe executando, são 2:
  • new, this.
Não fiquei muito preocupado pois você verá essas palavras tantas vezes que talvez nunca mais consiga esquecê-las.
Até o nosso próximo post.

Declarar Classes - Parte 3

No post anterior vimos que uma classe pode ter dois níveis de acesso: publico e padrão. Para dar à classe acesso publico, utilizamos o modificador public, para o padrão basta não colocar nada. Além dos modificadores de acesso à classe, o java possui outros modificadores que também podem ser aplicados a classes, mas que não estão relacionados ao acesso a estas. Os modificadores são:

  • strictfp
  • final
  • abstract

O modificador strictfp pode ser utilizado tanto em classes quanto em métodos. Você não precisa saber muita coisa sobre ele, mas se quiser saber um pouquinho mais é só clicar aqui. Na realidade o que você precisa saber mesmo é que ele pode ser usado na declaração de um método ou de uma classe, seja ela final ou abstract.

Bem, já que tocamos no assunto, o modificador final pode ser utilizado para declara um método, propriedade (variável) ou uma classe. O modificador final quando usado em uma classe faz com esta não possa mais ser extendida, ou seja, a sua hierarquia chegou ao final (essa foi podre). Mas será que alguém pode querer que uma classe não possa ser extendida? Claro que sim. Inclusive a Sun pensa assim. A classe String é uma classe final, ou seja, você não pode herdar jamais de String. Isso pode ser escolhido também por uma questão de segurança ou qualquer coisa que o valha.

Para finalizar temos o modificador abstract. Ele pode ser utilizado em classes e em métodos. Vale lembrar que se uma classe tiver pelo menos um misero método abstrato esta classe deverá ser abstrata, porém uma classe pode ser abstrata e não ter nenhum método abstrato... Agora embolou tudo né?. Bem, primeiro precisamos saber o que é uma classe abstrata. Uma classe abstrata (abstract) é uma classe que não pode ser instanciada, ou seja, se você quiser usar uma algum dia desses, a única forma de fazê-lo será estendendo-a.

Quando você herdar de uma classe abstrata você terá a obrigação de implementar todos os métodos abstratos da mesma, a menos, é claro, que a sua classe também seja abstrata. O fato é que um dia alguém vai fazer uma classe concreta e ela vai ter que definir todos, eu disse, todos os métodos abstratos não implementados de toda a árvore de herança... eu não faria isso se fosse você! E se os meus métodos forem todos concretos? Aí você ganhará um monte de método por herança, legal né?

Você pode combinar os modificadores a vontado... quer dizer, quase né. Os modificadores final e abstract nunca poderão ser combinados, pois isso causará uma crise de existência no compilador java. Uma classe final não pode ser nunca extendida e uma classe abstract deve ser obrigatoriamente extendida... entendeu por que não dá pra combinar né? Ah, o strictfp pode ser usado tanto em classes finais como em abstratas.
Agora para fixar os conceitos vamos trazer alguns exemplos do que vimos até aqui.


Animal.java
//posso combinar strictfp e abstract
//Essa classe deverá ser herdada por alguém
public strictfp abstract class Animal {

//Esse método precisa ser implementado
//em alguma subclasse concreta
public abstract void emitirSom();

//Esse método será herdado por todas as subclasses
public strictfp void contarAteDez() {
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
}
}

Dog.java
// Esta classe não poderá ser herdada por ninguém mais
public final strictfp class Dog extends Animal {

//Implementou o método abstrato, ou sobrescreveu.
@Override
public void emitirSom() {
System.out.println("Auf auf");
contarAteDez(); //posso chamar o método herdado aqui também
}

}

ViraLata.java
//ViraLata não pode herdar de Dog
//pois Dog é uma classe final
public class ViraLata extends Dog {

}

A classe Animal é uma classe abstrata e faz uso também do modificador strictfp. Essa classe possui um método abstrato que deverá obrigatoriamente ser implementado por uma subclasse concreta e possui um método concreto que será herdado por todas as subclasses. A classe Dog estende a classe Animal e implementa o seu método abstrato emitirSom, podemos ver que ela chama o método contarAteDez que foi herdado de Animal, ou seja, o nosso cachorro herdou a capacidade de contar até dez do animal. E por fim a classe ViraLata tenta sem sucesso estender a classe Dog que é uma classe final e não pode ser estendida nem sob a mira de uma arma.

No próximo post vamos aprender a nomear nossas classes e vamos trazer também a lista de palavras reservadas da linguagem java. Até lá.

domingo, 24 de agosto de 2008

Declarar Classes - Parte 2

Continuando nosso estudo, iremos agora trazer a segunda parte do objetivo 1.1 que são os modificadores de acesso a classe do java.

O java possui quatro níveis de acesso, porém somente três modificadores de acesso.Parece esquisito mas é isso mesmo. Os modificadores são:

  • public
  • protected
  • private

A vida de um programador java é escrever classes. Mas acontece que essas classe precisam interagir com outras classes (de outros programadores, inclusive os da sun :)). E para que haja essa interação é necessário que a classe que você escreveu tenha 'acesso' às classes dos outros seres. E são os modificadores de acesso que vão definir quem pode acessar sua classe. Acredito que não exista nada mais óbvio do que isso, mas vamos continuar. O java possui dois níveis de acesso à classes: default e public. Peraí, mas você não disse que o java tinha quatro níveis de acesso? É verdade, mas falando em acesso a classe, só podemos utilizar dois deles. Nas próximas seções falaremos sobre os outros modificadores. Então a coisa fica assim:

  • Se você escreveu uma classe public, qualquer classe do mundo terá acesso a ela. E quando eu falo de acesso, é no sentido de poder criar uma instância ou um objeto da mesma.
  • Se você escreveu uma classe e NÃO colocou o modificador public nela, então, somente as classes que estivem dentro do mesmo pacote que ela poderão acessá-la. Ou seja, qualquer classe fora do seu pacote nem mesmo saberá que a sua classe existe.

Vamos colocar um pequeno exemplos para firmar o objetivo melhor:


Animal.java
package javeiro;

class Animal {

}

Cat.java
package zoo;

import javeiro.Animal;

class Cat extends Animal{

}

Temos um problema aí. A classe Animal está definida como default e está dentro do pacote javeiro. Isso torna a classe invisívei para qualquer classe fora do pacote javeiro. Assim, a classe Cat terá uma bela surpresa quando tentar herdar da classe animal, o compilador java vai dizer pra ela: Ei Cat, eu não sei que Animal é esse... bem na verdade isso foi uma transliteração do erro: zoo\Cat.java:4: cannot find symbol, mas dá no mesmo. O ponto aqui é que Cat não enxerga Animal, pois o acesso default garante que só as classes dentro de javeiro poderão enxergar Animal.

Não vou colocar o exemplo da classe public porque é óbvio demais. Se você escreveu uma classe e definiu o acesso dela como public, então não adianta chorar, todo mundo vai enxergar sua classe, não importa onde ela ou eles estejam.

Até o próximo post.