Fundamentos de Java Edmilson Prata – UNIGRANRIO – Junho/2008
Criação de objetos e a função do “new” A sintaxe geral para a criação de um objeto de qualquer tipo é:
TipoClasse nomePonteiro = new ConstrutorTipoClasse();
Exemplo: Pessoa umaPessoa = new Pessoa();
Pela tabela de precedência, o “new” é a primeira coisa a ser executada. Ele é responsável por instanciar um novo objeto da classe especificada. Para isto, o new realiza três operações:
Aloca memória na Heap para o novo objeto;
Promove a inicialização padrão para os atributos do objeto (por meio do construtor);
Retorna o endereço de memória onde está alocado o novo objeto.
O new envia uma mensagem para o novo objeto solicitando a execução do método construtor da classe, que é a segunda coisa executada para a criação do objeto. O método construtor é um método especial que o programador coloca na classe e que tem a responsabilidade de inicializar o novo objeto. Em Java, o método construtor é deve possuir o mesmo nome da classe (sempre!). Depois de instanciado o objeto, o operador de atribuição (=) será então executado. Ele fará com que o “ponteiro”, o que nós costumamos erroneamente chamar de “objeto” (no exemplo acima chamado de “umaPessoa”), passe a apontar para o objeto real, ou seja, o que foi criado pelo “new” e está no endereço de memória que o “new” retornou. A função de um ponteiro é justamente armazenar o endereço de memória onde está um dado objeto e apontar/indicar a localização deste para que possamos acessá-lo. Um ponteiro é semelhante a uma variável inteira, porém o número guardado faz referência a um endereço de memória e as operações com este tipo de variável sempre dizem respeito ao objeto apontado. Apesar de estarmos falando sobre “endereços de memória”, em Java não é possível saber de fato qual é o endereço real de um objeto na memória devido a aspectos de segurança.
Fundamentos de Java – Edmilson Prata – Junho/2008
Pág. 1
Garbage Colletion Em linguagens como C++ é dever do programador codificar os procedimentos para desalocação (liberação) de memória. Já em Java não há esta necessidade, pois esta tarefa é feita automáticamente pelo Garbage Colletion. Garbage Colletion é um processo é executado por uma “thread” (tarefa) que roda em paralelo com o programa recolhendo os objetos considerados “perdidos” e liberando a memória destinada a eles. Um objeto “perdido” é um objeto para o qual não há nenhum ponteiro ou referência na aplicação, ou seja, ele foi “abandonado” pelo programa por não ser mais necessário. Isto acontece, por exemplo, quando atribuímos “null” a um ponteiro e não há nenhum outro ponteiro fazendo referência para aquele endereço de memória. Veja o exemplo a seguir que demonstra esta situação: //Criado um novo objeto cujo endereço está no ponteiro “nome”: String nome = “Fulano da Silva”; //Ao atribuir null, o ponteiro perde o endereço do objeto //e o objeto passa a ficar perdido na memória: nome = null;
Não sabemos quando exatamente o “coletor de lixo” irá executar, porém, quando for executado, o processo removerá todos os objetos considerados “lixo” da memória.
Bytecode e JVM Cada classe escrita em Java deve ficar em um arquivo cujo nome é formado pelo nome da classe mais a extensão “.java”. Exemplo: se a classe se chama “Pessoa” o arquivo se chamará “Pessoa.java”. Ao submetermos o código que escrevemos para o compilador Java, ele não gera código de máquina, mas gera um código chamado de “bytecode”. Este é o código de máquina que só pode ser executado por um processador virtual, ou seja, um programa chamado JVM (Java Virtual Machine). Para cada classe compilada é gerado um arquivo com o bytecode produzido pelo compilador. O nome deste arquivo é formado pelo nome da classe mais a extensão “.class”. Como os arquivos “.class” estão em uma linguagem que pode ser interpretada pela JVM, os programas compilados em Java podem ser executados em qualquer sistema operacional, bastando que se tenha uma JVM para o sistema desejado. Por isso, diz-se que o Java é uma linguagem “neutra”, ou seja, ele é “livre” de plataforma, pois um programa em Java poderia ser executado em qualquer sistema. A JVM, responsável por executar os programas em Java, realiza as seguintes funções:
Carrega o bytecode com o “Class Loader”;
Se o bytecode veio de fonte externa (ex.Applet) ele passa por um verificador de ByteCode por motivos de segurança;
O interpretador repetidamente lê uma instrução e a executa.
Fundamentos de Java – Edmilson Prata – Junho/2008
Pág. 2
Características Gerais do Java:
Neutra: Podemos dizer que Java é uma linguagem neutra, pois o “bytecode” produzido não está vinculado a nenhum processador/sistema operacional específico.
Segura: Apesar de termos variáveis que são ponteiros, o Java não nos deixa manipular (ler ou alterar) o valor do endereço. Possui também extensiva verificação do bytecode (presença do mecanismo CRC).
Portátil: Pode ser executada em qualquer plataforma.
Alto desempenho: Apesar de ser interpretada, os programas executam rapidamente pois o processo de interpretação é simples.
Paralelizável: Suporta programação de “threads” (multitarefa), ou seja, tarefas que rodam “paralelamente” ou “concorrentemente”, dependendo da plataforma.
Dinâmica: As classes são carregadas em tempo de execução, de acordo com a necessidade, ou seja, a JVM só carrega uma classe quando houver necessidade. Estas classes podem ser atualizadas separadamente o que garante alta coesão e baixo acoplamento.
Abrangente: Além destas características, encontramos em Java uma série de tecnologias que permitem criar sistemas para uma série de tipos de aplicações diferentes.
Padrão para nomear identificadores
Classes devem começar com letra maiúscula; Ex: Pessoa, Turma, Aluno, Professor.
Atributos, métodos e variáveis locais devem começar com letra minúscula; Ex: nome, matricula, somar
Caso as classes, atributos e métodos apresentem nomes compostos, as demais palavras deverão começar com letra maiúscula; Ex: AlunoPosGraduação, telefoneCelular, getNome
Deve-se evitar separar as palavras com caracteres como “o traço baixo”;
Não se deve utilizar acentos e caracteres especiais;
Constantes deverão ter todas as letras maiúsculas e pode-se utilizar o traço baixo. Ex: TAMANHO_MÁXIMO, NÚMERO_DE_ELEMENTOS.
Fundamentos de Java – Edmilson Prata – Junho/2008
Pág. 3
Package Palavra reservada que indica a que pacote pertence a classe. Um pacote é um conjunto de classes agrupadas e que, supostamente, tratam de um mesmo assunto. A indicação do pacote fica sempre no início do arquivo, na verdade é a primeira instrução no arquivo. Fisicamente um pacote representa uma sub-pasta dentro da pasta do projeto. E no pacote que ficam os arquivos referentes às classes que pertencem a este pacote.
This É uma variável automática que está presente em todos os métodos “não-estáticos”, ou seja, métodos que pertencem aos próprios objetos. Esta variável não precisa ser declarada. O “this” é um ponteiro para o objeto que estiver executando o método em questão no momento da execução. A codificação de um método deve valer para qualquer objeto da classe em questão. Por este motivo, precisamos de algum recurso do objeto que faça referência a ele mesmo, ou seja, ao objeto que estiver executando o método. Para estas situações é eu utilizamos o “this”. Considere o seguinte código: public class Pessoa { private String cpf; public Pessoa(String cpf) { this.cpf = cpf; } }
O código cria uma classe chamada “Pessoa” com um atributo chamado “cpf” e um construtor que recebe um parâmetro também chamado de “cpf”. Dentro do construtor encontramos uma instrução com o “this” e esta instrução passa para o atributo “cpf” o dado que está no parâmetro “cpf”. Como os dois (atributo e parâmetro) têm o mesmo nome (cpf), não seria possível identificar sem o “this” a quem queremos nos referir (se ao atributo ou se ao parâmetro). Vemos claramente neste exemplo a importância do “this”. Ele resolve facilmente o problema fazendo uma referencia ao objeto em conjunto com o seu atributo. Neste caso a linha “this.cpf=cpf” pode ser interpretada como se fosse “esteObjeto.cpf = parametro”.
Return Indica que a execução de um método deve ser encerrada. Se a declaração do tipo de retorno do método é diferente de “void”, que indica “sem retorno”, o “return” deverá estar acompanhado de um valor ou ponteiro a ser devolvido para quem chamou o método.
Fundamentos de Java – Edmilson Prata – Junho/2008
Pág. 4
Método “main” public static void main (String args[]) { ...instruções... }
Estruturas de controle e repetição IF if ( condição ) { ...instruções... } else if ( condição ) { ...instruções... } else { ...instruções... }
FOR for ( int x=; ; ) { ...instruções... }
Exemplo (código que imprime os números de 1 a 10): for (int x=1; x<11; x++) { System.out.println(x); }
WHILE while ( condição ) { ...instruções... }
Fundamentos de Java – Edmilson Prata – Junho/2008
Pág. 5