- Em Java, todos os métodos são virtuais, ou seja, o código que será realmente executado só é determinado em tempo de execução.
- Assim sendo, cada chamada a um método em Java envolve a busca pela localização do código do método (ou mesmo a determinação de se o método é suportado ou não pelo objeto);
- Amarração dinâmica é menos eficiente;no entanto, é ela que permite o polimorfismo;
- Java usa sempre amarração dinâmica;
quarta-feira, 28 de novembro de 2007
Amarração dinâmica
Gerenciamento automático de memória
•Em Java não existem primitivas para alocação e desalocação de memória (Ex: malloc e free no C, new e delete no C++, new e dispose no Pascal).
•A memória utilizada por objetos que não são mais utilizados é recuperada por um mecanismo de coleta de lixo sobre o qual a aplicação não exerce nenhum controle.
•O resultado é maior consumo de memória (pois ela demora mais a ser liberada) e maior overhead de processamento, em troca de uma menor quantidade de bugs de programação:
•A memória utilizada por objetos que não são mais utilizados é recuperada por um mecanismo de coleta de lixo sobre o qual a aplicação não exerce nenhum controle.
•O resultado é maior consumo de memória (pois ela demora mais a ser liberada) e maior overhead de processamento, em troca de uma menor quantidade de bugs de programação:
•Eliminação dos memory leaks – vazamento de memória, ocorre quando uma porção de memória, alocada para uma determinada operação, não é liberada quando não é mais necessária.
•Eliminação dos buffer overflows - estouro de pilha ou transbordamento de dados, ocorre quando o tamanho de uma região de memória ultrapassa sua capacidade máxima de armazenamento.
Sobrescrita e sobrecarga
O Java permite que você tenha métodos com o mesmo nome, mas com assinaturas diferentes, isto chama-se sobrecarga. O interpretador determinará qual método deve ser invocado pelo tipo de parâmetro passado. Os trecho abaixo é válido para uma compilação Java.
...
public void print( int i ) { ... }
public void print( float f ) { ... }
public void print( String s) { ... }
...
Quando você escreve o código para chamar um desses métodos, a chamada deverá coincidir com tipos de dados da lista de parâmetros de algum dos métodos. Diferente da sobrecarga, a sobrescrita acontece quando um método existe em uma classe pai e é reescrito na classe filha para alterar o comportamento. A assinatura do método deve ser igual na classe pai e na classe filha.
...
public void print( int i ) { ... }
public void print( float f ) { ... }
public void print( String s) { ... }
...
Quando você escreve o código para chamar um desses métodos, a chamada deverá coincidir com tipos de dados da lista de parâmetros de algum dos métodos. Diferente da sobrecarga, a sobrescrita acontece quando um método existe em uma classe pai e é reescrito na classe filha para alterar o comportamento. A assinatura do método deve ser igual na classe pai e na classe filha.
this e super
Estas duas palavras-chave da linguagem são aplicadas a métodos não estáticos, ou seja, de instância. A this é utilizada para referenciar variáveis ou métodos da instância atual e o super é utilizada para associar a métodos da classe pai.
Por exemplo:
public class Pai {
public int lançar(int numero) {
return 6 \% numero;
}
}
public class Filho extends Pai {
private int numero;
...
public int lançar(int numero) {
if (numero == 0) {
return this.numero; // retorna o atributo da classe
}
super.lançar(numero); // Chave o lançar da classe pai.
}
}
A classe Pai possui um método lançar retornando um inteiro. A classe filho, que estende de Pai foi criada para tratar uma divisão por zero que poderá ocorrer na classe Pai. Portanto, se for zero, retorna um número predefinido como atributo na classe Filho, caso contrário retorna o resultado do cálculo da classe Pai. Este é um excelente exemplo de polimorfismo e sobrescrita de métodos que veremos a seguir.
O Java associa automaticamente a todas as variáveis e métodos referenciados com a palavra this. Por isso, na maioria dos casos torna-se redundante o uso em todas as variáveis da palavra this. Existem casos em se faz necessário o uso da palavra this. Por exemplo, você pode necessitar chamar apenas uma parte do método passando uma instância do argumento do objeto. (Chamar um classe de forma localizada);
Por exemplo:
public class Pai {
public int lançar(int numero) {
return 6 \% numero;
}
}
public class Filho extends Pai {
private int numero;
...
public int lançar(int numero) {
if (numero == 0) {
return this.numero; // retorna o atributo da classe
}
super.lançar(numero); // Chave o lançar da classe pai.
}
}
A classe Pai possui um método lançar retornando um inteiro. A classe filho, que estende de Pai foi criada para tratar uma divisão por zero que poderá ocorrer na classe Pai. Portanto, se for zero, retorna um número predefinido como atributo na classe Filho, caso contrário retorna o resultado do cálculo da classe Pai. Este é um excelente exemplo de polimorfismo e sobrescrita de métodos que veremos a seguir.
O Java associa automaticamente a todas as variáveis e métodos referenciados com a palavra this. Por isso, na maioria dos casos torna-se redundante o uso em todas as variáveis da palavra this. Existem casos em se faz necessário o uso da palavra this. Por exemplo, você pode necessitar chamar apenas uma parte do método passando uma instância do argumento do objeto. (Chamar um classe de forma localizada);
Interfaces
Interfaces foram concebidas para criar um modelo de implementação aumentando o baixo acoplamento entre determinadas partes de um software. Uma interface não pode possuir atributos de instância e nem métodos com implementação, mas pode possuir atributos de estáticos (de classe) e cabeçalhos de métodos que deverão ser desenvolvidos nas classes que implementarão a interface.
Muitas vezes as interfaces representam ações ou papéis para as classes. Um exemplo comum de interface é a Serializable que se encontra dentro do pacote java.io e é muito utilizada em aplicações corporativas. Quando uma classe implementa Serializable ela não precisa implementar nenhum método definido na interface, mas com esta ação o programador indica ao java que a classe pode ser serializada, transformada em um conjunto de bits para serem armazenados ou transmitidos. A serialização de uma instância armazena todos os seus dados e consegue criar um objeto semelhante na desserialização.
Muitas vezes as interfaces representam ações ou papéis para as classes. Um exemplo comum de interface é a Serializable que se encontra dentro do pacote java.io e é muito utilizada em aplicações corporativas. Quando uma classe implementa Serializable ela não precisa implementar nenhum método definido na interface, mas com esta ação o programador indica ao java que a classe pode ser serializada, transformada em um conjunto de bits para serem armazenados ou transmitidos. A serialização de uma instância armazena todos os seus dados e consegue criar um objeto semelhante na desserialização.
Resumo de orientação a objetos em Java
Java é uma linguagem orientada a objetos e, com isso, não é possível desenvolver nenhum programa sem seguir tal paradigma. Um sistema orientado a objetos é composto por um conjunto de classes e objetos bem definidos que interagem entre si, de modo a gerar o resultado esperado.
A Orientação à Objetos modela o mundo real com classes e instâncias. Cada classe é a estrutura de uma variável, ou seja, um tipo de dado. Nela, são declarados atributos e métodos que poderão ser executados ou acessados nas instâncias da mesma classe. As classes possuem uma função muito importante na modelagem orientada a objetos, elas dividem o problema, modularizam a aplicação e baixam o nível de acoplamento do software.
Variáveis de uma classe são chamadas de instâncias de classe. Por exemplo: Se existe uma classe Pessoa existe a instância (variável) pessoa que é do tipo Pessoa. Um Objeto, ou instância, é uma entidade cujas informações podem incluir desde suas características até suas atividades, ou seja, uma abstração de um domínio de um problema.
Abaixo há uma série de definições sobre a arquitetura de orientação a objetos em Java.
Pacote: Conjunto de classes e demais arquivos que possuem interesses comuns ou atuam com dependências entre si. Fisicamente são pastas do sistema operacional.
Instância, objeto: Uma variável do tipo de uma classe.
Construtor: Responsável por iniciar a criação e inicialização de uma instância de classe.
Método: Funções referenciados aquela classe.
Modificador de acesso: Descreve que outras classes podem ter acesso a classe que está se criando. Também é usado para indicar que uma classe pode ser acessada de fora de seu pacote.
Hierarquia de classes: Um grupo de classes que estão relacionadas por herança.
Superclasse: É a classe que é estendida por uma determinada classe.
Subclasse: É a classe que estende determinada classe.
Classe base: A classe de determinada hierarquia que é uma superclasse de todas as outras classes. A classe pai de todas.
A Orientação à Objetos modela o mundo real com classes e instâncias. Cada classe é a estrutura de uma variável, ou seja, um tipo de dado. Nela, são declarados atributos e métodos que poderão ser executados ou acessados nas instâncias da mesma classe. As classes possuem uma função muito importante na modelagem orientada a objetos, elas dividem o problema, modularizam a aplicação e baixam o nível de acoplamento do software.
Variáveis de uma classe são chamadas de instâncias de classe. Por exemplo: Se existe uma classe Pessoa existe a instância (variável) pessoa que é do tipo Pessoa. Um Objeto, ou instância, é uma entidade cujas informações podem incluir desde suas características até suas atividades, ou seja, uma abstração de um domínio de um problema.
Abaixo há uma série de definições sobre a arquitetura de orientação a objetos em Java.
Pacote: Conjunto de classes e demais arquivos que possuem interesses comuns ou atuam com dependências entre si. Fisicamente são pastas do sistema operacional.
Instância, objeto: Uma variável do tipo de uma classe.
Construtor: Responsável por iniciar a criação e inicialização de uma instância de classe.
Método: Funções referenciados aquela classe.
Modificador de acesso: Descreve que outras classes podem ter acesso a classe que está se criando. Também é usado para indicar que uma classe pode ser acessada de fora de seu pacote.
Hierarquia de classes: Um grupo de classes que estão relacionadas por herança.
Superclasse: É a classe que é estendida por uma determinada classe.
Subclasse: É a classe que estende determinada classe.
Classe base: A classe de determinada hierarquia que é uma superclasse de todas as outras classes. A classe pai de todas.
Palavras chave de Java
Java possui 49 palavras chave, todas elas são escritas em minúsculas:
byte - short - int - long - char - boolean - double - float - public - private - protected - static - abstract - final - strictfp - transient - synchronized - native - void - class - interface - implements - extends - if - else - do - default - switch - case - break - continue - assert - const - goto - throws - throw - new - catch - try - finally - return - this - package - import - instaceof - while - for - volatile - super
Possui três identificadores que são valores literais:
null, false, true
byte - short - int - long - char - boolean - double - float - public - private - protected - static - abstract - final - strictfp - transient - synchronized - native - void - class - interface - implements - extends - if - else - do - default - switch - case - break - continue - assert - const - goto - throws - throw - new - catch - try - finally - return - this - package - import - instaceof - while - for - volatile - super
Possui três identificadores que são valores literais:
null, false, true
segunda-feira, 26 de novembro de 2007
DOWNLOAD SEMINÁRIO
Para baixar o seminário no formato ppt clique no link abaixo:
http://www.miltoncps.110mb.com/Java.ppt
http://www.miltoncps.110mb.com/Java.ppt
Polimorfismo
Existem várias classificações e tipos de polimorfismo. C++ apresenta vários tipos de
polimorfismo . Java apresenta um conjunto mais reduzido evitando principalmente polimorfismos ad-hoc.
REDEFINIÇÃO DE MÉTODOS PARA UMA CLASSE HERDEIRA
Trata-se de um polimorfismo, pode serclassificado como polimorfismo de inclusão. Um método é uma redefinição de um método herdado, quando está definido em uma classe construída através de herança e possui o mesmo nome, valor de retorno e argumentos de um método herdado da classe pai. A assinatura do método tem que ser idêntica, ou seja, teremos redefinição quando uma classe filha fornece apenas uma nova implementação para o método herdado e não um novo método.
Se a classe filha fornecer um método de cabeçalho ou assinatura parecida com a do método
herdado (difere ou no número ou no tipo dos argumentos, ou então no tipo do valor de retorno)
então não se trata mais de redefinição, trata-se de uma sobrecarga, pois criou-se um novo método.
Uma chamada ao método herdado não mais é interceptada por esse novo método de mesmo nome.
O método tem o mesmo nome, mas é ligeiramente diferente na sua assinatura (o corpo ou bloco de código {} não importa), o que já implica que não proporciona o mesmo comportamento
(behaviour) do método da superclasse.
SOBRECARGA ( MÉTODOS E OPERADORES)
- SOBRECARGA DE MÉTODOS
Este tipo de polimorfismo permite a existência de vários métodos de mesmo nome, porém
com assinaturas levemente diferentes ou seja variando no número e tipo de argumentos e no valor de retorno. Ficaria a cargo do compilador escolher de acordo com as listas de argumentos os procedimentos ou métodos a serem executados.
- SOBRECARGA DE OPERADOR
Java não fornece recursos para sobrecarga de operador, o que é perfeitamente condizente
com a filosofia da linguagem. Seus criadores que acreditavam que a linguagem deveria ser
pequena, simples, segura de se programar e de se usar (simple, small, safe and secure).
A ausência de sobrecarga de operadores pode ser contornada definindo apropriadamente
classes e métodos.
CLASSES ABSTRATAS
Classes abstratas são poderosas, elas permitem: criação de listas heterogêneas, ocorrência de
“dynamic binding” e maior clareza no projeto de sistemas. Os packages que vem com a linguagem estão repletos de exemplos de classes abstratas.
Métodos abstratos, obrigatoriamente pertencem a classes abstratas, e são métodos desprovidos
de implementação, são apenas definições que serão aproveitadas por outras classes da hierarquia.
Exemplo de classe abstrata:
abstract class Forma {
protected float x,y; //visivel hierarquia abaixo
public void move(float dx,float dy)
{
this.x+=dx; this.y+=dy;
}
abstract public void mostra( ); //metodo abstrato
}
//Classe ponto
class Ponto extends Forma {
public Ponto(float ax,float ay) //omita o valor de retorno!
//garante o estado do objeto
{
this.x=ax; this.y=ay;
}
//move nao precisa ser redefinido
public void mostra()
{
System.out.println("("+this.x+","+this.y+")");
}
}
Classes abstratas X Interfaces:
Você deve estar achando que classes abstratas e interfaces são conceitos parecidos e que
podem ser usados com objetivos semelhantes. Cuidado! Uma classe pode estender uma única classe (que pode ser abstrata ou não), mas pode implementar várias interfaces. Além disso, interfaces não permitem declaração de atributos, enquanto que classes abstratas permitem. Interfaces estão mais ligadas a comportamento, enquanto que classes abstratas estão mais ligadas a implementação.
Herança
Existe uma visão um pouco tacanha de orientação a objetos como uma simples maneira de
organizar melhor o seu código. Essa visão é facilmente desmentida pelos conceitos de
encapsulamento, interfaces, packages e outros já apresentados. Neste tópico apresentaremos o
conceito de herança, fundamental para programação orientada a objetos e um dos fatores de sucesso desta como muito mais que uma simples maneira de organizar melhor seu código.
Um dos aspectos que distinguem objetos de procedimentos e funções é que o tempo de
existência de um objeto pode ser maior do que o do objeto que o criou. Isto permite que em
sistemas distribuídos objetos criados em um local, sejam passados através da rede para outro local e armazenados lá quem sabe na memória ou mesmo em um banco de dados.
REDEFINIÇÃO DE MÉTODOS HERDADOS
Uma classe filha pode fornecer uma outra implementação para um método herdado,caracterizando uma redefinição “overriding” de método. Importante: o método deve ter a mesma assinatura (nome, argumentos e valor de retorno), senão não se trata de uma redefinição e sim sobrecarga “overloading”. A redefinição garante que o método terá o mesmo comportamento que o anterior isto faz com que as subclasses possam ser atribuídas a variáveis da superclasse pois atendem a todas as operações desta.
INTERFACES, UMA ALTERNATIVA PARA HERANÇA MÚLTIPLA
Herança múltipla é a capacidade de uma classe herdar de duas ou mais classes, por exemplo a classe radio-relógio herdar da classe rádio e da classe relógio.
Java por motivos de simplicidade, abandona a idéia de herança múltipla, cedendo lugar ao
uso de interfaces. Interfaces são um conjunto de métodos e constantes (não contém atributos). Os métodos definidos na interface são “ocos” ou desprovidos de implementação. Classes podem dizer que implementam uma interface, estabelecendo um compromisso, uma espécie de contrato, com seus clientes no que se refere a prover uma implementação para cada método da referida interface.Ao cliente, pode ser dada a definição da interface, ele acaba não sabendo o que a classe é, mas sabe o que faz. Quem programa em Objective C, deve ver as interfaces como algo semelhante ao conceito de protocolos.
organizar melhor o seu código. Essa visão é facilmente desmentida pelos conceitos de
encapsulamento, interfaces, packages e outros já apresentados. Neste tópico apresentaremos o
conceito de herança, fundamental para programação orientada a objetos e um dos fatores de sucesso desta como muito mais que uma simples maneira de organizar melhor seu código.
Um dos aspectos que distinguem objetos de procedimentos e funções é que o tempo de
existência de um objeto pode ser maior do que o do objeto que o criou. Isto permite que em
sistemas distribuídos objetos criados em um local, sejam passados através da rede para outro local e armazenados lá quem sabe na memória ou mesmo em um banco de dados.
REDEFINIÇÃO DE MÉTODOS HERDADOS
Uma classe filha pode fornecer uma outra implementação para um método herdado,caracterizando uma redefinição “overriding” de método. Importante: o método deve ter a mesma assinatura (nome, argumentos e valor de retorno), senão não se trata de uma redefinição e sim sobrecarga “overloading”. A redefinição garante que o método terá o mesmo comportamento que o anterior isto faz com que as subclasses possam ser atribuídas a variáveis da superclasse pois atendem a todas as operações desta.
INTERFACES, UMA ALTERNATIVA PARA HERANÇA MÚLTIPLA
Herança múltipla é a capacidade de uma classe herdar de duas ou mais classes, por exemplo a classe radio-relógio herdar da classe rádio e da classe relógio.
Java por motivos de simplicidade, abandona a idéia de herança múltipla, cedendo lugar ao
uso de interfaces. Interfaces são um conjunto de métodos e constantes (não contém atributos). Os métodos definidos na interface são “ocos” ou desprovidos de implementação. Classes podem dizer que implementam uma interface, estabelecendo um compromisso, uma espécie de contrato, com seus clientes no que se refere a prover uma implementação para cada método da referida interface.Ao cliente, pode ser dada a definição da interface, ele acaba não sabendo o que a classe é, mas sabe o que faz. Quem programa em Objective C, deve ver as interfaces como algo semelhante ao conceito de protocolos.
Encapsulamento
Encapsulamento, “data hiding” é um conceito bastante importante em orientação a objetos.
Neste tópico vamos falar das maneiras de restringir o acesso as declarações de uma classe e a
própria classe, isto é feito através do uso das palavras reservadas public, private e protected
que são qualificadores.
Alguém pode estar se perguntando o porquê de se restringir o acesso a certas partes de uma
classe. A idéia é simples, devemos fornecer ao usuário, cliente de uma classe, o necessário e
somente o necessário para que ele tire proveito da funcionalidade desta classe. Os detalhes devem ser omitidos, somente a lista de operações a qual uma classe deve atender fica visíve
Os benefícios são muitos: clareza do código, minimização de erros, facilidade de extensão.
Talvez a facilidade de modificação seja o mais importante dos benefícios. Como a classe é
conhecida pela sua interface, é muito fácil mudar a representação interna sem que o cliente,
usuário, perceba a diferença Estaremos preocupados em separar design de implementação, Java é uma linguagem boa de se programar em termos de design e em termos de implementação.
Programar tendo em vista o design é também chamado de “programming in the large”,
enquanto que programar tendo em vista implementação, codificação é chamado e“programming in the small”. Alguns programadores experientes afirmam que Java se parece com C quando estamos preocupados com codificação, mas quando estamos preocupados com design, Java se assemelha a Smalltalk.
Com encapsulamento você será capaz de criar componentes de software reutilizáveis, seguros,
fáceis de modificar.
Mas então como controlar o acesso de atributos e métodos em uma classe? Simples, através
das palavras reservadas private, public e protected cujos significados quando qualificando
métodos e atributos (private e public podem também qualificar classes) são descritos abaixo:
public
Estes atributos e métodos são sempre acessíveis em todos os métodos de todas as classes. Este é o nível menos rígido de encapsulamento, que equivale a não encapsular.
private
Estes atributos e métodos são acessíveis somente nos métodos(todos) da própria classe. Este é o nível mais rígido de encapsulamento.
protected
Estes atributos e métodos são acessíveis nos métodos da própria classe e suas subclasses, o que será visto em Herança
Nada especificado, equivale “package”ou “friendly”
Estes atributos e métodos são acessíveis somente nos métodos das classes que pertencem ao “package” em que foram criados. Este modo de acesso é também chamado de “friendly”.
Neste tópico vamos falar das maneiras de restringir o acesso as declarações de uma classe e a
própria classe, isto é feito através do uso das palavras reservadas public, private e protected
que são qualificadores.
Alguém pode estar se perguntando o porquê de se restringir o acesso a certas partes de uma
classe. A idéia é simples, devemos fornecer ao usuário, cliente de uma classe, o necessário e
somente o necessário para que ele tire proveito da funcionalidade desta classe. Os detalhes devem ser omitidos, somente a lista de operações a qual uma classe deve atender fica visíve
Os benefícios são muitos: clareza do código, minimização de erros, facilidade de extensão.
Talvez a facilidade de modificação seja o mais importante dos benefícios. Como a classe é
conhecida pela sua interface, é muito fácil mudar a representação interna sem que o cliente,
usuário, perceba a diferença Estaremos preocupados em separar design de implementação, Java é uma linguagem boa de se programar em termos de design e em termos de implementação.
Programar tendo em vista o design é também chamado de “programming in the large”,
enquanto que programar tendo em vista implementação, codificação é chamado e“programming in the small”. Alguns programadores experientes afirmam que Java se parece com C quando estamos preocupados com codificação, mas quando estamos preocupados com design, Java se assemelha a Smalltalk.
Com encapsulamento você será capaz de criar componentes de software reutilizáveis, seguros,
fáceis de modificar.
Mas então como controlar o acesso de atributos e métodos em uma classe? Simples, através
das palavras reservadas private, public e protected cujos significados quando qualificando
métodos e atributos (private e public podem também qualificar classes) são descritos abaixo:
public
Estes atributos e métodos são sempre acessíveis em todos os métodos de todas as classes. Este é o nível menos rígido de encapsulamento, que equivale a não encapsular.
private
Estes atributos e métodos são acessíveis somente nos métodos(todos) da própria classe. Este é o nível mais rígido de encapsulamento.
protected
Estes atributos e métodos são acessíveis nos métodos da própria classe e suas subclasses, o que será visto em Herança
Nada especificado, equivale “package”ou “friendly”
Estes atributos e métodos são acessíveis somente nos métodos das classes que pertencem ao “package” em que foram criados. Este modo de acesso é também chamado de “friendly”.
Efeito Colateral
Observe o exemplo:
//Classe ponto
class Ponto {
public float x,y;
.
.
.
}
//Classe principal
class Principal {
public static void main(String args[]) {
//preparacao das variaveis copia de objetos
Ponto pOriginal,pAlias,pCopia;
pOriginal=new Ponto((float)0.0,0.0f);
pAlias=pOriginal; //copiando atraves de atribuicao
pCopia=new Ponto(pOriginal.x,pOriginal.y); //copiando atributo por atributo
}
Preparacao das variaveis, copia de objetos:
pAlias e uma referência para o mesmo local de memória que pOriginal, por este motivo
quando pAlias é alterado, pOriginal se altera por “efeito colateral”, eles compartilham o mesmo
objeto pois a atribuição pAlias=pOriginal, copia o endereço de pOriginal.
Já pCopia, é o resultado de uma nova alocação de memória, portanto um novo endereço, um
objeto independente dos outros.
Comparacao de objetos:
pOriginal==pAlias e outras comparações equivalentes têm o significado de comparação do
endereço de memória e não do conteúdo.
pOriginal.x==pCopia.x tem o significado de comparação do valor desses atributos, assim
como uma comparação entre inteiros. Se esses atributos por sua vez fossem objetos, esta operação teria o significado de comparação entre endereços de memória dos objetos.
//Classe ponto
class Ponto {
public float x,y;
.
.
.
}
//Classe principal
class Principal {
public static void main(String args[]) {
//preparacao das variaveis copia de objetos
Ponto pOriginal,pAlias,pCopia;
pOriginal=new Ponto((float)0.0,0.0f);
pAlias=pOriginal; //copiando atraves de atribuicao
pCopia=new Ponto(pOriginal.x,pOriginal.y); //copiando atributo por atributo
}
Preparacao das variaveis, copia de objetos:
pAlias e uma referência para o mesmo local de memória que pOriginal, por este motivo
quando pAlias é alterado, pOriginal se altera por “efeito colateral”, eles compartilham o mesmo
objeto pois a atribuição pAlias=pOriginal, copia o endereço de pOriginal.
Já pCopia, é o resultado de uma nova alocação de memória, portanto um novo endereço, um
objeto independente dos outros.
Comparacao de objetos:
pOriginal==pAlias e outras comparações equivalentes têm o significado de comparação do
endereço de memória e não do conteúdo.
pOriginal.x==pCopia.x tem o significado de comparação do valor desses atributos, assim
como uma comparação entre inteiros. Se esses atributos por sua vez fossem objetos, esta operação teria o significado de comparação entre endereços de memória dos objetos.
Ponteiros
Ponteiros não existem nessa linguagem. Existem estudos que afirmam que erros com ponteiros são um dos principais geradores de “bugs” em programas, além disso com todos os recursos que Java oferece não precisaremos deles.
Os programadores acostumados ao uso de ponteiros (e aos erros decorrentes desse uso),
acharão muito natural e segura a transição para Java onde passarão a usar principalmente vetores e classes. A estruturação de seu código deverá agora ser feita em um modelo que se baseia no uso de objetos (vetores e Strings também são objetos). Objetos superam a representatividade obtida com records, funções isoladas e ponteiros.
De certo modo você estará usando referências, mas de forma implícita. Por exemplo: objetos
são alocados dinamicamente com new, eles são referências ou ponteiros para posições na
memória, mas a linguagem mascara este fato por razões de segurança. Como objetos são ponteiros (só que transparentes para você), nos depararemos com o problema de reference aliasing quando discutirmos cópia de objetos com outros objetos como atributos.
domingo, 18 de novembro de 2007
Operadores bitwise
Os operadores bitwise são aqueles que alteram o valor das variáveis em operações lógicas diretamente no processador, tornando-as muito mais performáticas. Estas operações são geralmente chamadas de tratamento por bits pois são operações que comparam e modificam a variável bit por bit. São eles:
Op : Nome : Uso : Descrição
~ : Inversão : ~x : Inversão dos bits de x.
& : E lógico : x & y : AND bit a bit entre x e y.
| : OU lógico : x | y : OR bit a bit entre x e y.
^ : OU excl. lógico : x ^ y : XOR bit a bit entre x e y.
<< : Desloc. a esq. : x << y : Desloc. a dir os bits de x, y vezes.
>> : Desloc. a dir. : x >> y : Desloca a direita os bits de x, y vezes.
>>> : Desloc. a dir. : x >>> y : Preenche zero a esquerda de x, y vezes.
Op : Nome : Uso : Descrição
~ : Inversão : ~x : Inversão dos bits de x.
& : E lógico : x & y : AND bit a bit entre x e y.
| : OU lógico : x | y : OR bit a bit entre x e y.
^ : OU excl. lógico : x ^ y : XOR bit a bit entre x e y.
<< : Desloc. a esq. : x << y : Desloc. a dir os bits de x, y vezes.
>> : Desloc. a dir. : x >> y : Desloca a direita os bits de x, y vezes.
>>> : Desloc. a dir. : x >>> y : Preenche zero a esquerda de x, y vezes.
Operadores relacionais e lógicos
Os operadores relacionais e lógicos são utilizados em testes e condições de entrada em um fluxo do programa. Abaixo estão todos eles relacionados:
Op : Nome : Uso : Descrição
> : Maior que : x > y : x maior que y.
>= : Maior ou igual a : x >= y : x maior ou igual a y.
< : Menor que : x <><= : Menor ou igual a : x <= y : x menor ou igual a y. == : Igual a : x == y : x igual a y.
!= : Diferente de : x != y : x diferente de y.
! : NÃO lógico (NOT) : !y : contrário de y.
&& : E lógico (AND) : x && y : x e y.
|| : OU lógico (OR) : x ||y : x ou y.
instanceof : Verif Instância : x instanceof X : x é instância da classe X
Obs.: Java executa curto-circuito.
Op : Nome : Uso : Descrição
> : Maior que : x > y : x maior que y.
>= : Maior ou igual a : x >= y : x maior ou igual a y.
< : Menor que : x <><= : Menor ou igual a : x <= y : x menor ou igual a y. == : Igual a : x == y : x igual a y.
!= : Diferente de : x != y : x diferente de y.
! : NÃO lógico (NOT) : !y : contrário de y.
&& : E lógico (AND) : x && y : x e y.
|| : OU lógico (OR) : x ||y : x ou y.
instanceof : Verif Instância : x instanceof X : x é instância da classe X
Obs.: Java executa curto-circuito.
Operadores aritméticos
Operadores aritméticos são aqueles que efetuam operações aritméticas em um ou mais tipos primitivos.
A seguir são apresentados os operadores aritméticos unários, que atuam sobre um único identificador:
Operador : Nome : Uso : Descrição
++ : Incremento : var++ / ++var : Retorna e adiciona / adiciona e retorna.
-- : Decremento : var-- / --var : Retorna e subtrai / subtrai e retorna.
- : Negativo : -var : Inverte o sinal da variável
+ : Positivo : +var : Não tem efeito.
Abaixo estão os operadores aritméticos que atuam sobre duas variáveis:
Op Nome Uso Descrição
+ Adição x + y Soma x com y.
- Subtração x - y Subtrai y de x.
* Multiplicação x * y Multiplica x por y.
/ Divisão x / y Divide x por y.
% Resto x % y Resto da divisão de x por y.
A seguir são apresentados os operadores aritméticos unários, que atuam sobre um único identificador:
Operador : Nome : Uso : Descrição
++ : Incremento : var++ / ++var : Retorna e adiciona / adiciona e retorna.
-- : Decremento : var-- / --var : Retorna e subtrai / subtrai e retorna.
- : Negativo : -var : Inverte o sinal da variável
+ : Positivo : +var : Não tem efeito.
Abaixo estão os operadores aritméticos que atuam sobre duas variáveis:
Op Nome Uso Descrição
+ Adição x + y Soma x com y.
- Subtração x - y Subtrai y de x.
* Multiplicação x * y Multiplica x por y.
/ Divisão x / y Divide x por y.
% Resto x % y Resto da divisão de x por y.
Identificadores
Os identificadores em Java iniciam com uma letra, um sublinhado "_" ou um sinal de dólar " $ " e podem possuir números após o primeiro caractere da palavra. Pela premissa de ser case-sensitive existe uma diferenciação entre letras maiúsculas e minúsculas.
Identificadores válidos são:
identificador, meu_Carro, MeuCarro2, _atributo, $bola _2seg
Identificadores usados para determinar nomes de variáveis, atributos de classe ou de instância, parâmetros e métodos.
Identificadores válidos são:
identificador, meu_Carro, MeuCarro2, _atributo, $bola _2seg
Identificadores usados para determinar nomes de variáveis, atributos de classe ou de instância, parâmetros e métodos.
Tipos Primitivos
Existem somente oito tipos primitivos em Java, todo o resto é objeto. Estes tipos ficaram na linguagem pela sua velocidade de interação, e por isso não foram transformados em Objetos. Como não são objetos a sua declaração já cria a variável em memória não necessitando de construtores.
Numéricos inteiros:
Todos esses tipos possuem uma representação interna em complemento de dois. O valor default para esses atributos é 0 e cada vez que se usar uma constante numérica no código fonte ela será um int a não ser que se especifique outro tamanho. Todos os tipos inteiros têm sinal.
byte - Inteiro 8-bit , faixa: -128 até 127short - Inteiro 16-bit, faixa:-32768 até 32767int - Inteiro 32-bit, faixa:-2147483648 até 2147483647long - Inteiro 64-bit, faixa: -9223372036854775808 até 9223372036854775807Ponto flutuante:
Por padrão, código fonte, tudo o número com decimais será um float e todo float que não for inicialiazado recebe o valor 0.0.
float - Ponto flutuante 32-bitdouble - Ponto flutuante 64-bit
Caractere:
O caractere guarda o valor traduzido de um código ASCII. Seu valor default é o código zero, \ 0.
O char também pode ser representado por um numero inteiro de 16 bits sem sinal, ou seja, pode-se atribuir à uma variável char o valor 100 ou o valor 65535, pois se está operando com os valores da tabela Unicode que representam caracteres de qualquer idioma.
O tipo String, como não é primitivo, é usado para representar uma seqüência de caracteres.
Constantes do tipo caractere aparecem entre apóstrofes: ‘a’, ‘1’, ‘$’.
char -16-bit: O tipo char é representado com 16-bits sem sinal, o que permite endereçar de 0 a 65535.O char também pode ser representado por um numero inteiro de 16 bits sem sinal, ou seja, pode-se atribuir à uma variável char o valor 100 ou o valor 65535, pois se está operando com os valores da tabela Unicode que representam caracteres de qualquer idioma.
O tipo String, como não é primitivo, é usado para representar uma seqüência de caracteres.
Constantes do tipo caractere aparecem entre apóstrofes: ‘a’, ‘1’, ‘$’.
Booleano:
Tipos boleanos identificam verdadeiro ou falso e podem ser utilizados diretamente em expressões de retorno para testes como if, switch, while e for., porém não podem ser comparados com variáveis ou constantes numéricas como em C. Valor padrão é o false.
boolean - true ou false. Tamanho de 8 bit.
Tipos boleanos identificam verdadeiro ou falso e podem ser utilizados diretamente em expressões de retorno para testes como if, switch, while e for., porém não podem ser comparados com variáveis ou constantes numéricas como em C. Valor padrão é o false.
Máquina Virtual Java
Programas Java não são traduzidos para a linguagem de máquina como outras linguagens estaticamente compiladas e sim para uma representação intermediária, chamada de bytecodes.
Os bytecodes são interpretados pela máquina virtual Java (JVM - Java Virtual Machine). Muitas pessoas acreditam que por causa desse processo, o código interpretado Java tem baixo desempenho. Durante muito tempo esta foi uma afirmação verdadeira. Porém novos avanços têm tornado o compilador dinâmico (a JVM), em muitos casos, mais eficiente que o compilador estático.
Java hoje já possui um desempenho próximo do C++. Isto é possível graças a otimizações como a compilação especulativa, que aproveita o tempo ocioso do processador para pré-compilar bytecode para código nativo. Outros mecanismos ainda mais elaborados como o HotSpot da Sun, que guarda informações disponíveis somente em tempo de execução (ex.: número de usuários, processamento usado, memória disponível), para otimizar o funcionamento da JVM, possibilitando que a JVM vá "aprendendo" e melhorando seu desempenho. Isto é uma realidade tão presente que hoje é fácil encontrar programas corporativos e de missão crítica usando tecnologia Java. No Brasil, por exemplo, a maioria dos Bancos utiliza a tecnologia Java para construir seus home banks, que são acessados por milhares de usuários diariamente. Grandes sítios como o eBay utilizam Java para garantir alto desempenho. E a cada ano Java tem se tornado mais rápido, na medida que se evolui o compilador dinâmico.
Essa implementação no entanto tem algumas intrínsecas. A pré-compilação exige tempo, o que faz com que programas Java demorem um tempo significativamente maior para começarem a funcionar. Soma-se a isso o tempo de carregamento da máquina virtual. Isso não é um grande problema para programas que rodam em servidores e que deveriam ser inicializados apenas uma vez. No entanto isso pode ser bastante indesejável para computadores pessoais onde o usuário deseja que o programa rode logo depois de abri-lo.
O Java ainda possui uma outra desvantagem considerável em programas que usam bastante processamento numérico. O padrão Java tem uma especificação rígida de como devem funcionar os tipos numéricos. Essa especificação não condiz com a implementação de pontos flutuantes na maioria dos processadores o que faz com que o Java seja significativamente mais lento para estas aplicações quando comparado a outras linguagens.
Os bytecodes são interpretados pela máquina virtual Java (JVM - Java Virtual Machine). Muitas pessoas acreditam que por causa desse processo, o código interpretado Java tem baixo desempenho. Durante muito tempo esta foi uma afirmação verdadeira. Porém novos avanços têm tornado o compilador dinâmico (a JVM), em muitos casos, mais eficiente que o compilador estático.
Java hoje já possui um desempenho próximo do C++. Isto é possível graças a otimizações como a compilação especulativa, que aproveita o tempo ocioso do processador para pré-compilar bytecode para código nativo. Outros mecanismos ainda mais elaborados como o HotSpot da Sun, que guarda informações disponíveis somente em tempo de execução (ex.: número de usuários, processamento usado, memória disponível), para otimizar o funcionamento da JVM, possibilitando que a JVM vá "aprendendo" e melhorando seu desempenho. Isto é uma realidade tão presente que hoje é fácil encontrar programas corporativos e de missão crítica usando tecnologia Java. No Brasil, por exemplo, a maioria dos Bancos utiliza a tecnologia Java para construir seus home banks, que são acessados por milhares de usuários diariamente. Grandes sítios como o eBay utilizam Java para garantir alto desempenho. E a cada ano Java tem se tornado mais rápido, na medida que se evolui o compilador dinâmico.
Essa implementação no entanto tem algumas intrínsecas. A pré-compilação exige tempo, o que faz com que programas Java demorem um tempo significativamente maior para começarem a funcionar. Soma-se a isso o tempo de carregamento da máquina virtual. Isso não é um grande problema para programas que rodam em servidores e que deveriam ser inicializados apenas uma vez. No entanto isso pode ser bastante indesejável para computadores pessoais onde o usuário deseja que o programa rode logo depois de abri-lo.
O Java ainda possui uma outra desvantagem considerável em programas que usam bastante processamento numérico. O padrão Java tem uma especificação rígida de como devem funcionar os tipos numéricos. Essa especificação não condiz com a implementação de pontos flutuantes na maioria dos processadores o que faz com que o Java seja significativamente mais lento para estas aplicações quando comparado a outras linguagens.
Principais Características
A linguagem Java foi projetada tendo em vista os seguintes objetivos:
- Orientação a objeto - Baseado no modelo de Smalltalk e Simula67;
- Portabilidade - Independência de plataforma;
- Recursos de Rede - Possui extensa biblioteca de rotinas que facilitam a cooperação com protocolos TCP/IP, como HTTP e FTP;
- Segurança - Pode executar programas via rede com restrições de execução;
- Sintaxe similar a Linguagem C/C++.
- Facilidades de Internacionalização - Suporta nativamente caracteres Unicode;
- Simplicidade na especificação, tanto da linguagem como do "ambiente" de execução (JVM);
- É distribuída com um vasto conjunto de bibliotecas (ou APIs);
- Possui facilidades para criação de programas distribuídos e multitarefa (múltiplas linhas de execução num mesmo programa);
- Desalocação de memória automática por processo de coletor de lixo (garbage collector);
- Carga Dinâmica de Código - Programas em Java são formados por uma coleção de classes armazenadas independentemente e que podem ser carregadas no momento de utilização.
Histórico
Em 1991, na Sun Microsystems, foi iniciado o Green Project, o berço do Java, uma linguagem de programação orientada a objetos. Os mentores do projeto eram Patrick Naughton, Mike Sheridan, e James Gosling. O objetivo do projeto não era a criação de uma nova linguagem de programação, mas antecipar e planejar a “próxima onda” do mundo digital. Eles acreditavam que, em algum tempo, haveria uma convergência dos computadores com os equipamentos e eletrodomésticos comumente usados pelas pessoas no seu dia-a-dia.
Para provar a viabilidade desta idéia, 13 pessoas trabalharam arduamente durante 18 meses. No verão de 1992 eles emergiram de um escritório de Sand Hill Road no Menlo Park com uma demonstração funcional da idéia inicial. O protótipo se chamava *7 (leia-se “StarSeven”), um controle remoto com uma interface gráfica touchscreen. Para o *7, foi criado um mascote, hoje amplamente conhecido no mundo Java, o Duke. O trabalho do Duke no *7 era ser um guia virtual ajudando e ensinando o usuário a utilizar o equipamento. O *7 tinha a habilidade de controlar diversos dispositivos e aplicações. James Gosling especificou uma nova linguagem de programação para o *7. Gosling decidiu batizá-la de “Oak”, que quer dizer carvalho, uma árvore que ele podia observar quando olhava pela sua janela.
O estouro da Internet aconteceu e rapidamente uma grande rede interativa estava se estabelecendo. Era este tipo de rede interativa que a equipe do *7 esperava. Gosling foi incumbido de adaptar o Oak para a Internet e em janeiro 1995 foi lançada uma nova versão do Oak que foi rebatizada para Java. A tecnologia Java tinha sido projetada para se mover por meio das redes de dispositivos heterogêneos, redes como a Internet. Agora aplicações poderiam ser executadas dentro dos browsers nos Applets Java e tudo seria disponibilizado pela Internet instantaneamente. Foi o estático HTML dos browsers que promoveu a rápida disseminação da dinâmica tecnologia Java. A velocidade dos acontecimentos seguintes foi assustadora, o número de usuários cresceu rapidamente, grandes fornecedores de tecnologia, como a IBM anunciaram suporte para a tecnologia Java.
Desde seu lançamento, em maio de 1995, a plataforma Java foi adotada mais rapidamente do que qualquer outra linguagem de programação na história da computação. Em 2003 Java atingiu a marca de 4 milhões de desenvolvedores em todo mundo. Java continuou crescendo e hoje é uma referência no mercado de desenvolvimento de software. Java tornou-se popular pelo seu uso na Internet e hoje possui seu ambiente de execução presente em web browsers, mainframes, SOs, celulares, palmtops e cartões inteligentes, entre outros.
Assinar:
Postagens (Atom)