A pedidos do alpharagga, aquitah o tuto q fiz há um tempão(quando li a JLS)…Não editei-verifiquei nada, portanto, se forem vendo os erros, eu corrijo.Taí cara:
[quote]
:::::: estado das variáveis:Tipos,Acessibilidade e Passagens de parâmetro:::::::::::::::::
Nesse artigo,o leitor terá uma breve noção de como se comportam as variáveis no Java,quais
são os seus tipos associados,como são acessadas,armazenas em memória e como são passadas para métodos.Esse tutorial está longe de esgotar esses assuntos,mas será uma boa visão aos iniciantes na linguagem Java.
A compreensão de como uma passagem de parâmetro é efetuada,ou como uma variável é acessada e modificada,é fundamental ao aprendizado de qualquer linguagem de programação.
Como nunca custa nada lembrar,aí vão alguns conceitos básicos envolvidos que o programador tem que saber:
-Classe: É o modelo ou a forma a partir da qual um objeto é criado.Nela existe a definição
das variáveis e seus atributos e como as coisas irão funcionar no seu escopo(dentro dessa classe).Toma-se como padrão a primeira letra do nome da classe em maiúscula(como String, Math, System…entre outras).
-Objeto: É uma instância da classe, componente na memória com seus atributos e dados próprios,que utilizam seus métodos para manipular os seus dados internos e que se comunicam
entre si através de mensagens(chamadas) a esses objetos.
-Instância: é a ocorrência em memória(heap) de uma determinada classe,cujos dados são definidos pela classe a qual essa instância faz parte.Só existe após o objeto ser criado.
Percebeu a diferença entre Objeto e instância?Exemplo prático(repare os comentários): [/quote]
[code]
public class Classe{
private static String variavel_de_classe=“Sou local a Classe”;
private String i=“Sou uma variável de instância”;
public static void main(String []guj){
Classe c;//declara um objeto(referência) c do tipo Classe,na sua stack(pilha).
c=new Classe();/*instância,é a ocorrência de c na heap,criada apartir do new()
agora,a variável c é visível em memória----representa a classe Classe--- */
System.out.println(variavel_de_classe);
}//fim do main
}//fim da classe Classe [/code]
Por hora,tudo que precisamos saber é que a stack armazena variáveis com escopo de método(que serão executadas dentro de métodos) e a heap armazena nossos objetos.Na verdade,
fazem muito mais do que isso.Não se preoucupe, pois exploraremos bem o assunto mais adiante.
:::Variáveis e acessibilidade:::
1.1-As variáveis no Java.
Antes de mais nada,devemos levar em conta que a linguagem Java é fortemente tipada,isto é,
toda e qualquer variável ou expressão tem um tipo associado conhecido em tempo de compilação.O nome de uma variável deve começar com uma letra e pode possuir os seguintes caracteres:‘A’-‘Z’,‘a’-‘z’.‘0’-‘9’,’_’ ou qualquer caracter unicode que represente uma letra,lembrando que todo nome de variável é sensível a alteração de caixa(case sensitive).
Os tipos em Java são divididos em 2 categorias:
-Os tipos primitivos(short,int,boolean,char,byte,long,float,double).
Esses tipos primitivos podem ser booleanos(boolean) ou numéricos(os demais).
Os numéricos por sua vez podem ser Integrais(byte,short,int,long e char) ou Pontos Flutuantes(float e double).
-limites e valores que armazena:
para byte, de -128 até 127,(inclusive)-armazena 8bits
para short,de -32768 até 32767,(inclusive)-armazena 16bits
para int, de -2147483648 até 2147483647,(inclusive)-armazena 32bits
para long, de -9223372036854775808 até 9223372036854775807,(inclusive)-armazena 64bits
para char, de ‘\u0000’ até ‘\uffff’(inclusive), que é, de 0 até 65535 do Unicode.
-tipos booleanos podem assumir apenas um dos 2 valores:true ou false.armazenam 8 bits.
para float,de -3.4E38 a 3.4E38-32 bits
para double,de -1.7E308 a 1.7E308-64 bits
-Os tipos referência(Classes,Objetos e Interfaces).Veremos mais detalhes desse tipo no próximo tópico.
Obs:Há um terceiro tipo(Null Type) que não iremos nos ocupar pois ele não pode ser declarado,por não possuir um nome;nem permitir coerção(conversão de tipo-casting) para esse tipo.Uma referência nula é apenas um possível valor para uma expressão de tipo null.Essa referência pode sempre ser convertida para qualquer tipo referência.Na prática,a única coisa que o programador precisa saber é que null é um literal que pode ser de qualquer tipo referência.
1.1.1-Quanto á atribuição de valores.
Devemos levar em conta que uma variável é um nome associado a uma posição(endereço hexadecimal) de memória.Na sua declaração,o compilador “arranja”(aloca) um espaço para ela.
Ela(a variável) tem um tipo associado,ás vezes conhecido como “tipo em tempo de compilação”,que possui um dos tipos anteriormente citados.Uma variável de um tipo primitivo sempre armazena um valor de seu tipo exato.Em uma variável de tipo referência devemos possuir alguma atenção:
-Se ela é uma variável de referência do tipo Classe:
Considerando uma classe Guj,ela pode armazenar uma referência a null ou uma referência a uma instância de Guj,ou qualquer subclasse de Guj.
-Se ela é uma variável de referência do tipo Interface:
Ela pode armazenar uma referência a null ou uma referância a qualquer instância de qualquer classe que implementa essa interface.
-Se ela é referência do tipo Objeto:
a)Se ela é pertencente a um Array:
Se x é de um tipo primitivo então uma variável do tipo Array de x,pode armazenar uma referência a null ou uma referência a qualquer Array do tipo “Array de x”;se x é do tipo referência,então a variável do tipo “Array de x” pode armazenar uma referência a null,ou uma referência a qualquer Array de um tipo y,considerando que y tem tipo atribuível a x.
b)Se ela é um Objeto:
Uma variável do tipo Object pode armazenar uma referência a null ou uma referência a qualquer Objeto;seja instância de uma Classe,Interface ou Array.Nunca é demais lembrar que Object é a superclasse de todas as outras classes.Logo,qualquer classe que o leitor crie,já é herdeira(é uma subclasse) de Object e seus respectivos 11 métodos.
1.1.2-tipos identificáveis em uma classe:
Existem 7 tipos de variáveis identificáveis em uma classe Java.A saber:
1-Variável de Classe:
é um campo declarado com a palavra-chave static dentro de uma declaração de classe,ou com ou sem static dentro de uma declaração de interface.
2-Variável de Instância:
é um campo declarado dentro de uma declaração de classe sem a palavra-chave static.
3-componentes de um Vetor(Array):
são variáveis sem nome que são criadas e inicializadas com valores padrão sempre que um novo objeto que é um Array é criado.
4-parâmetros para métodos:
são nomes de argumentos cujos valores são passados para um método.Para cada parâmetro declarado em uma declaração de método,uma nova variável de parâmetro é criada cada vez que um método é invocado.
5-parâmetros para Construtores:
são nomes de argumentos cujo valores são passados para um construtor.Para cada parâmetro declarado em uma declaração de um construtor,uma nova variável de parâmetro é criada cada vez que uma instância é criada ou uma chamada explícita ao construtor é executada.
6-parâmetro para tratar uma exceção:
é criado cada vez que uma exceção é capturada por uma cláusula catch em um bloco try-catch.A nova variável é inicializada com o Objeto associado com a exceção.
7-variáveis locais:
São variáveis locais aquelas limitadas ao escopo(alcance) de uma instrução ou método.Quando um fluxo de controle entra em um bloco ou uma instrução for,uma nova variável é criada para cada variável local declarada nessas instruções ou campos.Uma instrução de declaração de uma variável local pode conter uma expressão que inicializa a variável.Uma variável local com uma expressão de inicialização não é inicializada,entretanto,até a sua instrução de declaração que a declara ser executada.Se não fosse uma excepcional situação,poderíamos dizer que uma variável local é sempre criada quando uma instrução ou bloco a qual foi declarada é executada.Uma excepcional condição ocorre quando em uma instrução switch,aonde é possível o controle de entrada no bloco pular a execução de uma instrução que declara uma variável local.Seu ciclo de vida é no máximo o método a qual está inserida.
vejamos um simples código:
[code]
import java.io.*;
public class Variaveis{
private float sal; //1
private static String nome;//2
private final static int id=10;//3
Variaveis(){ //4
}
Variaveis(float x,String y){//5
this.sal=x;
this.nome=y; }
public static void main(String []args){
Variaveis v=new Variaveis();//6 v é local a main
v.sal=5000;
nome=“Paulo”;
Object o[]=new Object[]{"J","U","G"};//7
exibir(o);//8
System.out.println(+v.sal);//9
System.out.println(nome); //10
System.out.println(id); //11
try{ //12
PrintWriter grava =new PrintWriter(new FileWriter("c:\entrada.txt"));
grava.println("Registro :"+id);
grava.println("Nome :"+nome);
grava.println("Salario :"+v.sal);
grava.close();
}
catch(Exception erro){ //13
erro.printStackTrace();
System.err.println("Erro de Arquivo!");
}
}
protected static void exibir(Object []object){//14
for(int i=2;i>=0;i–){
System.out.print(object[i]); }
System.out.println();
}
}//fim da classe Variáveis
[/code]
Nesse programa temos a presença de vários tipos de variáveis.Vamos analisar cada trecho(siga os comentários):
em (1) temos uma variável de instância sal do tipo float;
em (2) temos uma variável de classe(repare no static) chamada nome do tipo String;
em (3) temos uma outra variável de classe(id) com a palavra-chave final.isso indica que a ela só pode ser atribuído um valor uma única vez.E uma vez atribuído,ela terá sempre esse mesmo valor(é uma constante).
em (4) e (5) temos um construtor vazio(sem parâmetros) e um recebendo os parâmetros de construtores x e y respectivamente.Esse trecho de código referentes a construtores é totalmente desnecessário(é apenas para ilustrar o tipo de variável),pois nenhuma variável é passada na criação da instância de classe em (6).Poderia deixar sem construtor nenhum,pois java proveria um vazio para classe.Mas jamais poderia deixar somente o construtor com parâmetros-em (5)-,pois daria um erro de compilação,uma vez que em (6):
Variaveis v=new Variaveis();
nenhum valor é passado a instância da classe criada no método main!
Nota:v é uma instância de classe,mas é local a main.ela pode acessar variáveis de classe e
instância,mas não pode ser acessada de lugar algum senão o próprio método em que é criada.
-continuando:
em v.sal=5000; atribuímos a variável de instância sal o valor 5000
repare que é necessário utilizar uma instância da classe v para acessar sal.Isso ocorre porque ela não é estática(static).Em nome=“Paulo”; podemos atribuir diretamente pois ela é de classe.Esse modificador(static) garante a variável que só haverá uma instância dela em memória.
em (7) criamos um array do tipo Object cujos índices receberam J,U e G como parâmetros;
em (8) fazemos uma chamada ao método exibir() passando a variável de referência o como parâmetro;
em (9),(10) e (11) passamos parâmetros ao método println() para mostrá-los na tela.Repare
que as duas variáveis de classe(com o static) são passadas diretamente(sem a variável de referência v),sal,que é de instância,precisa ser acessada da forma objeto.variável;
em (12),temos o início de um bloco try-catch,try tenta executar o código para gravar um arquivo de texto em disco.para isso usamos um rescritor de caracteres da classe java.io.FileWriter(por isso é necessário dar um import java.io.* e uma instancia chamada grava de java.io.PrintWriter que através das chamadas ao método println(parametro) nos permite gravar em disco os dados.depois fechamos o recurso utilizado através de grava.close();
pondo o programa para executar( javac Variaveis.java ) vc verá que na sua tela aparecerá:
GUJ
5000.0
Paulo
10
e no seu drive C: será criado o arquivo entrada.txt com os dados:
Registro :10
Nome :Paulo
Salario :5000.0
note que na tela e no arquivo o numero inteiro 5000 passado a float sal foi convertido para 5000.0.Isso ocorre porque a conversão do tipo float para int é permitida.Veremos uma tabela de conversão de tipos primitivos no final desse tópico.
em (13),temos uma cláusula catch com o parâmetro erro(do tipo Exception).Se um erro ao tentar gravar esse arquivo entrada.txt ocorrer,a execução do programa será desviada para catch,e a chamada a erro.printStackTrace(); exibirá na tela a pilha de erros apartir do ponto em que ocorreram.a chamada a System.err.println() é somente para tornar mais explícita (e personalizado)ao programador que um erro ocorreu.
e finalmente em (14),temos o corpo do método exibir que recebe um array de object como parâmetro,conta seus índices do final para o início,para exibí-los na tela(transformará J,U,G em GUJ).
Nesse exemplo(Variaveis.java) vimos vários tipos de variáveis,mas devemos observar que isso é apenas um humilde pedaço do poderoso mundo que é Java.
No que tange variáveis vale a pena salientar que:
-Uma dada variável nao pode ser declarada mais de uma única vez,ou ocorreria um erro de compilacao. Ela pode ser inicializada uma unica vez, e escrita/lida quantas vezes for necessário.
-O custo de declarações locais é NULO em termos de instruções utilizadas pela CPU para alocação de espaço. Já o custo de inicializar essas variaveis deve ser considerado.
-variáveis locais também são chamadas de variáveis de pilha,temporárias e ou de método.
-Variáveis de instância também são chamadas de atributos,propriedades ou campos.
-Uma variável de instância e uma variável de método podem possuir o mesmo nome;nesse caso uma referência this deve ser usada dentro do método aonde está localizada a variável local para chamar a variável de instância.(this faz referencia ao objeto “classe” a qual está inserido).
-Toda variável local tem que ser inicializada antes de ser usada.
-Variáveis de Instância são inicializadas com valores padrão caso não seja feito explicitamente pelo Programador assim que um objeto da classe a qual está inserida é instanciado.
-Variáveis de um tipo mais restritivo(exemplo int) não podem receber um conteúdo de um tipo
mais abrangente(exemplo double),pois dará erro de compilação!Será necessário uma coerção(ou casting) para permitir isso.Ex: double d=(double)i;//onde i é um inteiro
Vejamos uma tabela padrão de valores default de variáveis não explicitamente inicializadas:
padrão.gif
O número de conversões e tipos são tão grandes em Java,que esse assunto merece um tutorial á parte só para isso.Por hora,mostraremos uma tabela com as conversões permitidas entre os tipos primitivos(as que ocorrem com mais frequencia)em seus programas Java,só a título de curiosidade:
Amplia.gif
Nota:Conversões de Ampliação de um tipo numérico primitivo não causam perda no valor da ordem de grandeza da variável,desde que ela(a classe ou método) esteja com o modificador strictfp,que força todos os métodos a aderirem as regras IEE754,tornando possível saber o comportamento de números double ou float,independente da plataforma.Caso não esteja com esse modificador,poderão ocorrer perdas em números float e double.Em números int e long,o uso de
strictfp evita uma perda de valores na sua conversão para float ou double arredondando para um valor válido mais próximo possível.
reduz.gif
Nota:Conversões de Redução de um tipo numérico primitivo podem causar perdas na ordem de grandeza da variável e perder a precisão quanto ao seu valor real.
-Variáveis de instância e métodos,também são chamados de membros de classe e podem fazer uso de modificadores de acesso,ao contrário das variáveis locais.Veremos mais sobre o assunto no próximo tópico.