quarta-feira, 31 de março de 2010

[Java] Determinar o número de elementos de uma matriz


Para determinar o número de elementos de uma matriz basta verificar o valor da variável de instância lenght (comprimento) da matriz desejada. A variável length armazena o número de elementos de uma matriz.

Exemplo


System.out.println("O número de elementos é: "+ matriz.lenght);

[Java] Explicar como inicializar os elementos de uma matriz


Este assunto já foi abortado neste post.

[Java] Explicar porque os elementos de uma matriz são inicializados


Os elementos de uma matriz devem ser inicializados para "reservar" o espaço de memória da matriz. Quando uma matriz é inicializada, é reservado na memória o espaço necessário para todos os elementos da matriz. Se uma referência a uma antiga matriz for utilizada para reservar uma nova matriz, a anterior será perdida e posteriormente "limpada" da memória pelo garbage collector.

[Java] Declarar e criar matrizes de tipos de primitivas, de classes e de matrizes


Declarando matrizes

Matrizes servem para agrupar valores de dados de um mesmo tipo e finalidade. Como foi visto neste post matrizes podem ser declaradas para qualquer tipo de primitiva, mas além de tipos de primitivas podem também ser declaradas como classes ou também outras matrizes (matriz de matriz).

Quando as matrizes são declaradas cria-se um espaço na memória por referência, como pode ser visto na última figura do post passado.

Declarando matrizes de objetos

Matrizes de objetos funciona da mesma maneira que as matrizes de primitivas, porém ao invés de conter um valor de tipo primitivo, contém um objeto. Veja no exemplo abaixo como declarar, instanciar e inicializar esse tipo de matriz.
Data[] vetorDatas;
vetorDatas = new Data[3];
vetorDatas[0] = new Data(07, 04, 1986);
vetorDatas[1] = new Data(03, 11, 1985);
vetorDatas[2] = new Data(31, 03, 2010);
Matrizes de objetos podem ser declarados, instanciados e inicializados como da forma acima, mas também da seguinte forma:
Data[] vetorData = {new Data(07, 04, 1986),
new Data(03, 11, 1985),
new Data(31, 03, 2010)};
Declarando matrizes de matrizes

Da mesma forma que matrizes de primitivas e matrizes de objetos, funcionam as matrizes de matrizes. Matrizes de matrizes são comumente chamadas também de matrizes multidimensionais. Veja a figura abaixo para visualizar sua utilidade e funcionamento.


No exemplo acima, se tentar acessar a posição vetorDeVetor[1][5] (que não existe) irá retornar uma exceção do tipo java.lang.ArrayIndexOutOfBoundsException. Informando justamente que o índice que foi acessado excede a matriz.

[Java] Definir valores de matrizes com atributo de comprimento e um loop


Mesmo com a simplificação utilizando matrizes para controlar e manipular várias variáveis em comum, iniciar os campos da matriz um por um continua um trabalho dispendioso, porém, podemos atribuir valores para cada campo da matriz utilizando de um valor de tamanho da matriz e um loop. Vejamos abaixo como realizar esta tarefa.

Exemplo
int[] numeros;
numeros = new numeros[40];

for (int contador=0; contador < numeros.length; contador++){
numeros[contador] = contador;
}
Neste exemplo, numeros.length retorna o tamanho da matriz numeros, que no nosso exemplo acima é 40. Cada campo da matriz irá receber o valor da posição em que ele se encontra. Com esse exemplo pode-se modificar e atribuir o que for necessário para cada posição.

[Java] Codificar matrizes unidimensionais


Muitas vezes precisamos gravar vários valores em apenas uma variável. Por exemplo, para gravar as notas de uma turma de 40 alunos, seria muito trabalhoso criar e manipular 40 variáveis diferentes, assim uma variável com 40 campos seria mais simples e fácil de se manipular e controlar, não é? Geralmente com esse intuito são utilizados as matrizes.

Matrizes com apenas uma dimensão são comumente chamadas de vetores. Veja a figura abaixo para entender um pouco sobre as matrizes unidimensionais.

Um fator importante a ser lembrado é que em java os vetores quando declarados possuem a posição inicial como 0 (zero). Assim, em um vetor (chamado vetor) de 10 posições a ultima posição não é vetor[10] e sim vetor[9]. Abaixo veremos como declarar, instanciar, inicializar e manipular matrizes unidimensionais.

Declarando uma matriz unidimensional

Sintaxe

tipo[] identificadorDaMatriz;

Exemplos

int[] notas;
string[] nomes;
double[] salarios;

Instanciando uma matriz unidimensional

Sintaxe

identificadorDaMatriz = new tipo[tamanhoDaMatriz];

Exemplos

notas = new int [40];
nomes = new String[10];
salarios = new double [5];


Inicializando uma matriz unidimensional

Sintaxe

identificadorDaMatriz[posicaoNaMatriz] = valor;

Exemplos

notas[1] = 7;
notas[2] = 8;
notas[3] = 6;
notas[4] = 4;
...
nomes[10] = "Carina";
nomes[1] = "Cristina";
nomes[5] = "Mariana";
...
salarios[5] = 880.00;
salarios[3] = 4522.35;
...

Declarando, instanciando e inicializando uma matriz unidimensional em um comando

Sintaxe

tipo[] identificadorDaMatriz = {lista dos valores separados por vírgula, ex: valor1, valor2, valor3, ..., valorn};

Exemplo

int[] notas = {3, 4, 7, 10, 5, 6, 4, 7, 8, 10, 9};
String[] nomes = {"Carina", "Cristina", "Mariana", "Juliana", "Carol", "Mara"};
double[] salaraios = {330.40, 444.44, 4523.55, 1851.38};

Acessando um valor em uma matriz unidimensional

Exemplos

int nota = notas[1]; //nota fica igual ao valor da segunda posição do vetor notas
System.out.println(salario[4]); //imprime a quinta posição do vetor salario

Até agora tudo bem, mas como são armazenadas as matrizes de primitivas na memória? Para visualizar melhor, veja a figura abaixo comparando como são armazenadas variáveis primitivas e matrizes de primitivas.



[Java] Criação e uso de matrizes


Os posts seguintes trataram sobre a criação e o uso de matrizes. Os tópicos abordados serão: Codificar matrizes unidimensionais (vetores), Definir valores de matrizes com atributos de comprimento e loop, Declarar e criar matrizes de tipos de primitivas, de classes e de matrizes, Explicar porque os elementos de uma matriz são inicializados, Explicar como inicializar os elementos de uma matriz, Determinar o número de elementos de uma matriz, Criar uma matriz multidimensional e Passar argumentos para o método main para o uso em um programa.

quinta-feira, 25 de março de 2010

[Java] Serializar e desserializar objetos


Serialização de objetos

Quando necessitamos ler ou gravar um objeto inteiro a partir de um arquivo, em Java, podemos utilizar do mecanismo de serialização de objetos. Um objeto serializado é representado como uma sequência de bytes que inclui os dados do objeto bem como as informações sobre o tipo do objeto e os tipos dos dados armazenados no objeto. Depois que um objeto serializado foi gravado em um arquivo, por exemplo, ele pode ser lido a partir do arquivo e ser desserializado(os dados representados em bytes podem agora ser utilizadas para recriar o objeto na memória).

Para que os objetos de uma classe possam ser serializados é necessário que a classe implemente a classe Serializable.

Serializable é uma interface de tags em Java utilizada apenas para identificar classes cujos objetos podem ser serializados (gravados) ou desserializados (lidos) de algum tipo de armazenamento (como por exemplo arquivo em disco ou campo de banco de dados) ou transmitidos por rede. Essa interface possui nenhum método. Mas porque então deve-se usar a interface Serializable para serializar objetos se esta classe possui NENHUM método? A resposta é simples. Apenas para "marcar" que seus objetos podem ser serializados.

Em uma classe que implementa Serializable o programador deve ter certeza que cada variável de instância da classe é do tipo Serializable. Qualquer variável de instância que não necessitar de ser Serializable deve ser declarada como transient para indicar que não é Serializable e deve ser ignorada durante o processo de serialização.

Por padrão todas as variáveis de tipos primitivos podem ser serializados, porém alguns cuidados devem ser tomados com variáveis de tipos por referência, para essas, deve ser verificado a definição da classe e possivelmente das superclasses (classes pais) para assegurar que o objeto é serializável. Objetos de array são serializáveis por padrão, entretanto, se o array contiver referências a outros objetos, esses objetos podem ou não serem serializáveis.

[Java] Criar construtores para inicializar objetos


Construtores são utilizados para inicializar um objeto de uma classe quando o objeto for criado. Não é obrigatória a implementação de um construtor. Ao se utilizar a palavra-chave new o construtor da classe é chamado para realizar a inicialização do objeto. Quando não é explicitamente criado o construtor java, o compilador java utiliza um construtor padrão sem parâmetros. O construtor padrão java tem a seguinte foma:
[NomeDaClasse]()  { super(); }
Esta função chama o construtor padrão (sem parâmetros) da classe pai. Quando esta classe "não" herda de ninguem, a função super() irá chamar o construtor da classe Object, já que todas as classes em Java herdam de Object

Construtores são úteis para inicializar as variáveis de seu objeto, por exemplo se você possui uma classe chamada relógio que possui ano, mês, dia, hora, minuto e segundo, pode ser útil ao se criar um objeto relógio que seja passado como parâmetros ano, mês, dia, hora, minuto e segundo para uma inicialização personalizada do objeto relógio.

Construtores possuem grande semelhança com métodos e assim como os métodos, os construtores também podem ser sobrecarregados.

Sintaxe
[modificador] [nomeDaClasse] ([parâmetros]){
Código_do_bloco
}

Como pode ser observado, os constutores devem obrigatoriamente possuir o mesmo nome que a classe que o contém e não possuem tipo de retorno.

quarta-feira, 24 de março de 2010

[Java] Usar encapsulamento para proteger dados


Como dito anteriormente, uma vantagem do encapsulamento é que ele protege o acesso direto aos atributos de uma instância fora da classe onde estes foram declarados. Esta proteção consiste em se usar modificadores de acesso mais restritivos sobre os atributos definidos na classe.

Tipos de modificadore de acesso:
  • Se um atributo, método, construtor ou uma classe for declarado public, ele poderá ser utilizado em qualquer lugar.
  • Se um atributo, método ou construtor for declarado private, ele só poderá ser utilizado (referenciado) na definição da classe onde o mesmo é definido.
  • Se um atributo, método ou construtor for declarado protected, ele só poderá ser utilizado no pacote onde o mesmo é definido ou na definição de uma subclasse da classe onde o mesmo é definido.
  • Se um atributo, método, construtor ou uma classe não for declarado com um dos qualificadores discutidos acima, ele só poderá ser utilizado no pacote onde o mesmo é definido.
Para visualizar melhor o acesso de dados veja a tabela abaixo:

Modificador/Acesso

própria classe

mesmo pacote

subclasse em outro pacote

todos restantes

public

SIM

SIM

SIM

SIM

protected

SIM

SIM

SIM

NÃO

default (sem modificador)

SIM

SIM

NÃO

NÃO

private

SIM

NÃO

NÃO

NÃO



[Java] Implementação de Encapsulamento e Construtores


Nestes próximos posts será tratado sobre o uso de encapsulamento para proteger os dados e a criação de construtores para a inicialização de objetos.

terça-feira, 23 de março de 2010

[Java] Usar métodos sobrecarregados


Métodos contidos em uma mesma classe podem ser declarados com um mesmo nome contanto que a sua assinatura seja diferente. Para isso o conjunto de parâmetros desses métodos não pode ser igual (numero, tipo e ordem dos parâmetros diferentes). A sobrecarga de método é geralmente utilizada para implementar métodos com mesmo nome que fazem tarefas iguais ou semelhantes, mas sobre tipos e números de argumentos diferentes e também nos construtores. Um ótimo exemplo de método sobrecarregado é o System.out.print().

Declarando métodos sobrecarregados

O modo de declarar métodos sobrecarregados é identico a declarar métodos normais. A única diferença é o cuidado que se deve ter ao declarar métodos carregados para que suas assinaturas sejam diferentes. Veja abaixo um exemplo de métodos carregados. Neste exemplo, o método sobrecarregado quadrado executa a tarefa de multiplicar um valor int, double ou string por ele mesmo e retorna o valor ao quadrado (No caso de um String apenas concatenar).

Classe com a declaração do método sobrecarregado:

public class MetodosSobrecarregados {
public int quadrado (int i){
return i*i;
}
public double quadrado (double i){
return i*i;
}
public String quadrado (String i){
return i+i;
}
}

Classe que testa o método sobrecarregado:

public class TestaSobrecarga {
public static void main(String[] args) {
int x = 2;
double y = 36.75;
String z = "CARINA_CALIXTO_";
MetodosSobrecarregados ms = new MetodosSobrecarregados();

System.out.println("Quadrado de " + x + ": " + ms.quadrado(x));
System.out.println("Quadrado de " + y + ": " + ms.quadrado(y));
System.out.println("Quadrado de " + z + ": " + ms.quadrado(z));
}
}

O resultado da execução deste programa é:
Quadrado de 2: 4
Quadrado de 36.75: 1350.5625
Quadrado de CARINA_CALIXTO_: CARINA_CALIXTO_CARINA_CALIXTO_


Como foi dito anteriormente, o compilador distingue entre os métodos quadrado diferentes a partir do parâmetro e não do retorno do método, assim se algum método mesmo possuindo tipo de retorno diferente, se seus parâmetros forem iguais o compilador não poderá distinguir entre os métodos qual o que será utilizado e acarretará assim em erro (o método [nomeDoMétodo] já está definido em [nomeDaClasse]).

[Java] Comparar métodos estáticos e de objeto


Métodos estaticos

Como já foi abordado neste post, a palavra-chave static faz com que os valores e operações feitas sejam compartilhado entre todas as instâncias. Métodos e variáveis não declarados como static, a cada nova instancia seria uma nova variável onde o valor/operações de uma instancia não iria interferir na outra. Nada melhor que um exemplo para entender melhor o que foi dito. O exemplo abaixo mostra tudo isso que foi dito.

class Classe1 {

public static int contStat = 0;
public int cont = 0;

public Classe1() {}

public static void incrContStat() {
contStat++;
System.out.println("contStat agora é "+ contStat);
}

public void incrCont() {
cont++;
System.out.println("cont agora é "+ cont);
}
}

public class TestaStatic {
public static void main(String args[]) {
Classe1 c1 = new Classe1();
c1.incrContStat();
c1.incrCont();

Classe1 c2 = new Classe1();
c2.incrContStat();
c2.incrCont();

Classe1 c3 = new Classe1();
c3.incrContStat();
c3.incrCont();

Classe1 c4 = new Classe1();
c4.incrContStat();
c4.incrCont();
}
}
A execução deste exemplo resulta em:

contStat agora é 1
cont agora é 1
contStat agora é 2
cont agora é 1
contStat agora é 3
cont agora é 1
contStat agora é 4
cont agora é 1


Além disso, métodos estáticos como dito no post anterior, não necessitam da criação de objetos para a chamada deste métodos, mesmo quando em classe diferente do método que o chama. Podem, desta forma, serem acessados diretamente.

Métodos de objeto

Métodos de objetos são aqueles não declarados como static. Para o acesso deste métodos é necessária a chamada através de um objeto como já explicado anteriormente.

[Java] Declarar e invocar um método


Como já foi abordado em post anterior sobre a declaração de um método, não será reescrito o post. Para visualizar sobre a sintaxe da declaração de um método, o que é um método e exemplos veja este post.

Invocando um método

Após construídos, os métodos podem ser invocados para realizar a tarefa a qual foram escritos. Para invocar um método que está em outra classe, deve-se criar um objeto do tipo da classe que contém o método a ser invocado e apartir deste objeto invocar o método. Quando o método está na mesma classe, basta apenas invocá-lo. Complicado? Nem tanto! Observe o exemplo abaixo (o mesmo do post anterior) para compreender melhor.

Exemplo:

Neste exemplo as classes diferentes são coloridas diferentemente, a vermelha contém apenas o método multiplica enquanto a azul possui o método main e o método multiplica. O método multiplica que está na mesma classe do método principal foi destacado de amarelo para melhorar a sua visualização.

//Operacao.java
public class Operacao {
public void multiplica(int x, int y){
int mult;
mult = x*y;
System.out.println("Multiplicação em outra classe: " + mult);
}
}

//TestaOperacoes.java
public class TestaOperacoes {

static public void multiplica(int x, int y){
int mult;
mult = x*y;
System.out.println("Multiplicação da mesma classe: " + mult);
}

public static void main(String[] args) {
int x = 5;
int y = 7;

//Testa multiplica em Operacao.java
Operacao operacoes = new Operacao();
operacoes.multiplica(x, y);

//Testa multiplica em TestaOperacoes.java
multiplica(x,y);
}
}
O resultado da execução deste exemplo seria:

Multiplicação em outra classe: 35
Multiplicação da mesma classe: 35

Como pode ser percebido, ao se invocar o método multiplica presente em outra classe foi necessário criar um objeto daquela classe para poder invocá-lo no seguinte formato: [objeto].[método]([atributosQuandoExistentes]);

Se o método chamado (calling) estiver presente na mesma classe que o método que o invoca (worker) não é necessário criar um objeto daquela classe que os contém. Assim a invocação fica no seguinte formato: [método]([atributosQuandoExistentes]);

Quando um método de trabalho (worker) for declarado como static, independente de sua localização (na mesma classe do método que o chama ou não) a chamada a este método pode ser feita da seguinte forma: [classeAQuePertence].[método]([atributosQuandoExistentes]);

Quando um método é invocado a execução do método de chamada (calling) "para" na linha em que foi feita a chamada ao outro método e retorna somente após a execução do método de trabalho (worker) chamado. métodos worker podem ou não exigir valores a serem entregues quando chamados, esses valores são comumente chamados de parâmetros. Da mesma forma métodos podem ou não retornar valor. Quando um método retorna nenhum valor ele é declarado como void. Para melhor entender, observe a figura abaixo.



sexta-feira, 12 de março de 2010

[Java] Definir os métodos de trabalho (worker) e de chamada (calling)


Para ajudar o esclarecimento da definição e exemplificação de métodos de trabalho (worker) e de chamada (calling), veja o exemplo abaixo.

//Operacao.java
public class Operacao {
public void multiplica(int x, int y){
int mult;
mult = x*y;
System.out.println("Multiplicação em outra classe: " + mult);
}
}

//TestaOperacoes.java
public class TestaOperacoes {

static public void multiplica(int x, int y){
int mult;
mult = x*y;
System.out.println("Multiplicação da mesma classe: " + mult);
}

public static void main(String[] args) {
int x = 5;
int y = 7;

//Testa multiplica em Operacao.java
Operacao operacoes = new Operacao();
operacoes.multiplica(x, y);

//Testa multiplica em TestaOperacoes.java
multiplica(x,y);
}
}
O resultado da execução deste exemplo seria:

Multiplicação em outra classe: 35
Multiplicação da mesma classe: 35

Para entender a definição de métodos calling e worker iremos também utilizar a analogia de um restaurante. Em um restaurante há os clientes e os garçons. Um cliente chama um garçom e faz um pedido, o garçom irá fazer o pedido do cliente e retornar com prato escolhido pelo cliente. Nesta analogia, o método calling seria o cliente e o método worker seria o garçom. Assim, método de chamada é aquele que invoca (chama) um outro método enquanto o método de trabalho (worker) executa o trabalho para qual foi invocado. No exemplo acima, o método main é o método calling quando chama os métodos multiplica tanto na mesma classe quanto em outra classe e os métodos multiplica seriam os métodos worker.

Considerações finais:
  • Não há limites para a quantidade de chamadas de métodos que um método de chamada pode fazer.
  • Como mostrado no post, o método de chamada pode estar na mesma classe ou em classe diferente do método de trabalho.
  • Apesar de um método de trabalho poder estar na mesma classe ou não de um método de chamada, as maneiras de invocar quando estão na mesma classe é diferente quando estão em classes diferentes.
  • Você pode escrever os métodos em qualquer ordem no seu código fonte (antes ou depois do método de chamada, antes ou depois de outro método de trabalho). Não necessariamente os métodos serão executados na ordem em que foram descritos na classe, essa ordem de execução não depende da ordem em que foram descritos, mas dependem da ordem em que foram invocados no método de chamada.

[Java] Desenvolvimento e uso de métodos


Nos próximos posts será tratado sobre o desenvolvimento e o uso de métodos na linguagem de programação Java. Descrever as vantagens dos métodos, definir métodos de trabalho (worker) e de chamada (calling), declarar e invocar um método, comparar métodos estáticos e de objeto e usar métodos sobrecarregados.

Vantagens de se utilizar métodos:
  • Métodos fazem com que os programas fiquem mais fáceis de ler e de manter o programa (modificar, consertar).
  • Métodos fazem com que o desenvolvimento e manuntenção do programa seja mais veloz.
  • Métodos permitem uma melhor reutilização de código.
  • Métodos permitem objetos separados se comunicarem e distribuirem o trabalho realizado pelo programa.

[Java] Criar loops do/while


O loop do tipo do/while é muito parecido com o loop while, com apenas uma diferença. Diferentemente do loop while, o bloco de comandos de um loop do/while será executado uma ou mais vezes. Ou seja, não importa se a condição do laço do/while é verdadeira ou falsa, a primeira execução do bloco sempre será executada. Veja a figura a seguir para compreender melhor o fluxo do loop do/while.



Sintaxe
do {
BlocoDeComando;
}
while (expressãoBoolean); // O ponto e vírgula é obrigatório!!!!

[Java] Desenvolver loops for


O loop do tipo for trabalha da mesma forma que o loop while, porém o loop for é usado para um número de iterações de pré definidas vezes. Da mesma forma que o loop while, o bloco de comandos de um loop for pode ser executado zero ou mais vezes.

Sintaxe
for (<inicializa[,inicializa]>; <expressãoBoolean>; <atualiza[,atualiza]>) {
blocoDeComando;
}
Assim como no loop while, no bloco do loop for pode conter qualquer tarefa como por exemplo outro comando de loop, construtores de decisão e etc.

Exemplos de uso do loop for

  • loop for único (imprimir os valores de 1 até 100)
for (int contador = 1; contador <= 100; contador++ ){
System.out.print(contador + " ");
}

  • loops for aninhados (escrever 3 linhas com 10 asteriscos em cada)
for (int contadorV = 1; contadorV <= 3; contadorV++ ){
for (int contadorH = 1; contadorH <= 10; contadorH++ ){
System.out.print("*");
}
System.out.println();
contadorH = 1;
}

[Java] Criar loops while


Loop while é um comando de loop que primeiramente verifica uma condição e enquanto (while) a condição descrita for verdadeira (true) o bloco de código do loop será executado.

Sintaxe
while (<expressãoBoolean>) {
blocoDoLoop; // contém as tarefas a serem executadas no loop
} // fim do loop while
// código do programa continua aqui
No bloco do loop pode conter qualquer tarefa como por exemplo outro comando de loop, construtores de decisão e etc. Para melhor entender o loop while, veja a figura abaixo com o funcionamento do fluxo do loop while.


Exemplos de uso do loop while

  • loop while (imprimir os valores de 1 até 100)
int contador = 1;
while ( contador <= 100 ){
System.out.print(contador + " ");
contador++;
}
  • loops while aninhados (escrever 3 linhas com 10 asteriscos em cada)
int contadorH = 1;
int contadorV = 1;
while ( contadorV <= 3 ){
while ( contadorH <= 10 ){
System.out.print("*");
contadorH++;
}
System.out.println();
contadorH = 1;
contadorV++;
}


[Java] Uso de construções de Loop


Contruções de loop (ou de laço) são instruções para executar um bloco de comandos de acordo com uma condição. Enquanto essa condição do loop for verdadeira o bloco do loop será executado. Há três dipos diferentes de contruções de Loop em Java, são eles:
  • while
  • for
  • do/while
Nos próximos posts será explicado o funcionamento de cada um desses comandos de loop. Existem alguns comandos de controle de fluxo importantes. são eles:
  • break
  • break com label
  • continue
  • continue com label
Break

Termina o loop e passa para o comando após o loop que contem o break. Em loops aninhados termina apenas o loop em que está contido e os internos nele contido.

Break com label

Termina o loop que possui a label. No exemplo abaixo o break não terminaria o do/while interno como normalmente faria pois está com label. Assim, neste exemplo, o comando break "pula" para o próximo comando fora do label setado, ou seja, executando o comandos_5.
fora:
do {
comandos_1;
do {
comandos_2;
if ( condição ) {
break fora;
}
comandos_3;
} while ( expr1 );
comandos_4;
} while ( expr2 );
comandos_5

Continue

Termina o loop e passa para a condição do loop que contem o continue. Em loops aninhados termina apenas o loop em que está contido e os internos nele contido voltando para a condição do loop que o contém.

Continue com label

Da mesma forma que o break com label, o continue com label termina o loop e passa para a condição do loop que contem a label.

sexta-feira, 5 de março de 2010

[Java] Usar a condição switch


Assim como os comandos if e if/else, o comando switch também é uma construção de controle e assim serve para selecionar tarefas a serem executadas dependendo de uma condição.

Sintaxe:

switch ( <expressão> ) {
case <constante1>:
<tarefa ou bloco de tarefas>*
[break;]
case <constante2>:
<tarefa ou bloco de tarefas>*
[break;]
...
default:
<tarefa ou bloco de tarefas>*
[break;]
}
Lembrando que a expressão deve retornar um valor de algum dos tipos: char, byte, short, int ou do tipo enum.

Exemplo:

switch ( numero ) {
case 1:
System.out.println("É o número 1!");
break;
case 2:
System.out.println("É o número 2!");
break;
default:
System.out.println("Não é o número 1 nem o número 2!");
break;
}



[Java] Criar construções if e if/else


Os contrutores de decisão if e if/else selecionam a tarefa a ser executada pelo programa dependendo de uma condição. Esta condição deve retornar um valor boolean ou ser uma variável boolean.

Sintaxe:
  • if
if(<condição>){
<executa tarefa(s)>
}


ou

if(<condição>)
<executa 1 tarefa>

  • if/else
if(<condição>){
<executa tarefa(s)>
}else{
<executa tarefa(s)>
}


A tarefa dentro de um bloco de comando if só irão ser executadas se a condição for true e quando houver o comando else, a tarefa dentro do bloco somente será executada se a condição do comando if for false. Dentro de um bloco if ou if/else pode ser executado qualquer tipo de tarefa, como por exemplo outros comandos if ou if/else criando assim if ou if/else aninhados.

Digamos que, por exemplo, deseja-se fazer um programa que receba um número do usuário e se ele for maior que 100 imprima "é maior que 100!". Este é um exemplo de um caso onde pode ser utilizado o comando if. Ele seria escrito da seguinte forma (considere que n foi o número entrado pelo usuário):

if(n>100){
System.out.println("é maior que 100!");
}

[Java] Reconhecer a compatibilidade de atribuições e a conversão necessária de tipos fundamentais


Este assunto já foi tratado em outro post. Para vê-lo clique aqui.

[Java] Identificar expressões booleanas e seus requisitos em construções de controle


Expressões booleanas

Utilizadas geralmente em construções de controle, expressões booleanas são úteis para resolver problemas lógicos como, por exemplo, determinar se uma variável é maior que outra. Devem sempre retornar um valor booleano (true ou false). Uma expressão booleana pode conter operadores de comparação ou operadores lógicos.

Relembrando:

Operadores de comparação: ==, !=, <, >, <=, >=.
Operadores lógicos: &&, ||

Cuidado!!

Tenha cuidado ao se comparar String em Java. Strings são objetos. Se você tentar compará-las com os operadores de comparação, você está comparando onde eles estão armazenados na memória (seu endereço) e não ao seu conteúdo. Para realizar a comparação de string utilize o método equals(). Como mostra o exemplo:

String nome1 = "Carina";
String nome2 = "Marina";
String nome3 = "Carina";
boolean igual = true;

igual = nome1.equals(nome2); //igual recebe false
igual = nome1.equals(nome3); //igual recebe true

quinta-feira, 4 de março de 2010

[Java] Identificar operadores relacionais e condicionais


Operadores relacionais

Descrição

Operador

É igual a

==

É diferente de

!=

Menor que

<

Menor ou igual a

<=

Maior que

>

Maior ou igual a

>=


Operadores condicionais

Descrição

Operador

uma condição E outra condição

&&

uma condição OU outra condição

||

Negação

!



[Java] Uso de operadores e construtores de decisão


Como o uso de operadores já foi abordado em vários posts que podem ser conferido aqui e em outros post será mais detalhado sobre os construtores de decisão, neste post será feito apenas um breve resumo sobre o uso dos operadores e construtores de decisão.

Operadores

Os operadores são utilizados para modificar as variáveis. Existem: Os operadores aritméticos, operadores de atribuição, operadores unários, operador instanceof, operadores de incremento e Decremento, operadores de comparação, operadores lógicos, operadores de bit.

Construtores de decisão

Construtores de decisão são comandos para selecionar as tarefas a serem realizadas pelo programa baseados em uma condição. São eles:
  • if-then
  • if-then-else
  • switch

quarta-feira, 3 de março de 2010

[Java] Comparar como as variáveis de referência de objetos são armazenadas em relação às variáveis primitivas


Há duas áreas distintas onde os dados de um programa são armazenados: stack e heap, então, para poder comparar como as variáveis são armazenadas deve-se primeiro saber as duas maneiras de armazenar variáveis em Java.

Heap

A JVM tem um heap que é compartilhada entre todas as threads. O heap é a área de dados de tempo de execução a partir do qual a memória de todas as instâncias de classes e matrizes é atribuída. Ele também tem variáveis de instância e área de método. Ou seja é uma área reservada para carregar instâncias de objetos e isso significa que embora a method area mantenha as todas as informações de uma classe é aqui que ficam todas as informações persistentes como valores de variáveis.

Coisas que residem no Heap:
  • Variáveis de instância
  • Referências a variáveis de instância
  • Objetos

Stack

Cada thread possui uma stack particular que é criada ao messo tempo da thread. Uma stack Java funciona da mesma maneira que a stack em outras linguagens convencionais como C. Variáveis locais, referências de variáveis locais e invocações de métodos são empilhados e desempilhados da stack.

Coisas que residem na Stack:
  • Variáveis locais
  • Referências de variáveis locais
  • Métodos
Para ficar mais claro, veja o exemplo abaixo:

Considerando que há uma classe Camisa contendo id, tamanho, preco e cor.
//Classe Camisa
public class Camisa {
public int id;
public int tamanho;
public double preco;
public String cor;

public Camisa(int id, int tamanho, double preco, String cor){
this.id = id;
this.tamanho = tamanho;
this.preco = preco;
this.cor = cor;

}
}
Iremos no exemplo criar uma variável de instância (instancia) e uma local (local), bem como duas variáveis de referência (primeiraCamisa e segundaCamisa) para exibir suas diferenças.
//Classe do exemplo
public class TesteHS {
public int instancia;
public static void main(String[] args) {
int local;
local = 10;
Camisa primeiraCamisa = new Camisa(0,40,29.90,"Amarelo");
Camisa segundaCamisa = new Camisa(1,42,49.90,"Rosa");

primeiraCamisa = segundaCamisa;
}
}
Antes do comando primeiraCamisa = segundaCamisa; as variáveis de referência e primitivas encontravam-se da seguinte forma:



Após o comando primeiraCamisa = segundaCamisa;:



Resumindo

variáveis locais (primitivas ou referências) pertencem a stack enquanto que uma variável de instância pertence a um heap. Porém, uma referência de uma variável local na stack aponta para um objeto na heap e o objeto não morre com a morte da referência. Os objetos que estão na heap que não estão a ser utilizados são, eventualmente, destruídos pelo garbage collector de forma a liberar a memória.

terça-feira, 2 de março de 2010

[Java] Declarar, instanciar e inicializar variáveis de referência de objetos


Declarar variáveis de referência de objetos

Como dito anteriormente, a declaração de variáveis de referência é basicamente a mesma coisa que a declaração de variáveis primitivas. Declara-se o tipo do Objeto a referenciar e o nome da variável (não necessariamente precisa criar o objeto no momento da declaração). A diferença é que o tamanho do espaço alocado para uma variável de referência é sempre fixo, porque se trata de um endereço de memória que mostra como chegar ao objeto que se refere.

Exemplo de declaração de variável de referência:

Idade minhaIdade;

Instanciar e inicializar variáveis de referência de objetos

Para inicializar variáveis de referência, basta utilizar o comando new como mostra a sintaxe abaixo:

<variavelDeReferencia> = new <TipoObjeto>();

Exemplo:

minhaIdade = new Idade();


Assim como as variáveis primitivas, também é válida a declaração e inicialização em apenas um comando, como mostra o exemplo abaixo:

Idade minhaIdade = new Idade();


A variável de referência serve para guardar a referência de um determinado objeto (instância) e permitir o acesso de seus métodos. Para acessar os métodos utiliza-se o nome da referência + “.” + método. Usando o mesmo exemplo anterior para expressar o acesso de um método.

minhaIdade.calcIdadeEmDias();

Assim uma instância da classe Idade acessa o método calcIdadeEmDias().

[Java] Criação e uso de objetos


Para entender a criação e uso de objetos, deve-se saber como declarar, instanciar e inicializar uma variável de referência a objetos e também como as variáveis de referência de objetos são armazenadas em relação as variáveis primitivas. Assim os próximos post irão tratar desses assuntos.

[Java] Usar intercalação de promoção e tipo


Intercalação de promoção significa que uma variável pode receber valor de variáveis de tipos com tamanho menor que o tipo que ela foi declarada ou a intercalação entre um valor inteiro para um valor de ponto flutuante (float ou double). Mesmo que você tenha um valor do tipo double, por exemplo, que caiba dentro de um int ele não permitirá a intercalação de promoção, já que não conhece o valor que você vai inserir.

Intercalação de tipo é o comumente conhecido como "cast". Ao fazer com que uma variável receba um valor de tipo maior que o que foi declarada, isso somente será possível se você informar o casting . Para fazer um cast basta colocar um parênteses com o tipo a ser recebido (<tipo>) da seguinte forma int i = (int)99L; ou int i = (int) variavelLong; onde variavelLong é do tipo long.

Sintaxe do casting:
  • identificador = (tipoDoReceptor) valor;
Exemplo de cast:

short a;
int b;
long c;

c = 1;

b = (int) c; //cast long -> int
a = (short)b;
//cast int -> short

segunda-feira, 1 de março de 2010

[Java] Descrever como inicializar variáveis de instância


Como já foi dito no post anterior, variáveis de instância possuem em sua declaração, modificador de acesso. Já foi mostrado em um post anterior como declarar variáveis de instância (ou atributos), porém colocarei aqui e acrescentarei mais um detalhe para revisar.

Declarando uma variável de instância (atributo) em Java

Sintaxe básica para declaração de um atributo em Java:
<modificador>* <tipo> <nome> [ = <valorinicial> ];
Exemplos:
private int x;
private float y = 10000.0F;
double z;
public String nome = "Carina Calixto"
Tipos de modificador de acesso que variáveis de instância admitem:
  • Private: A variável será "visível" apenas dentro da classe que a declarou
  • Default (sem modificador): A variável será visível para qualquer classe ou subclasse (a ser explicado) presentes no mesmo package.
  • Protected: A variável será visível para qualquer classe ou subclasse presentes no mesmo package e para subclasses de outros packages, apenas através do que foi herdado.
  • Public: A variável é totalmente visível.
Outros modificadores que variáveis de instância admitem:
  • Volatile: Utilizado em casos com multiplas threads, este modificador garante que o valor da variável volatile será sempre consistente efetuando a sincronização da cópia da thread com a cópia principal.
  • Transient: O uso desse modificador informa a JVM (Java Virtual Machine) para ignorar esta variável quando for serializar o objeto que a contém.
  • Final: Define uma entidade que não pode ser mais modificada.
  • Static: A variável de instância que utiliza esse modificador é compartilhada com todas as instâncias de sua classe, assim uma alteração do valor desse atributo em qualquer dos objetos, causará efeitos sobre esse atributos para todas as instância.
Uma variável de instância pode possuir apenas um modificador de acesso, porém pode receber mais de um modificador.

[Java] Diferenciar variáveis local e de instância


Variáveis locais são aquelas que são definidas dentro de um método ou de um bloco. Variáveis locais são válidas apenas no escopo em que estão inseridas (dentro do método ou bloco em que foram definidas). Variáveis de instância (ou também chamadas de variáveis membro ou atributo) são aquelas declaradas dentro de uma classe (fora de método senão seria local). Há algumas diferenças básicas entre variáveis locais e de instância. Na declaração de variáveis de instância, há a presença de modificadores, enquanto na declaração da variável local não. Variáveis locais não possuem valor default enquanto variáveis de instancia possuem.

Valores default das variáveis de instância:
  • Tipos Inteiros = 0
  • Pontos Flutuantes = 0.0
  • char = \u0000
  • boolean = false
  • Referência = null