Guia Certificação JAVA OCA 8 | O Básico de JAVA | Defina o escopo de variáveis


O escopo é o que determina em que pontos do código uma variável pode ser usada.


Variáveis locais

Chamamos de locais as variáveis declaradas dentro de blocos, como dentro de métodos ou construtores. Antes de continuar, vamos estabelecer uma regra básica: o ciclo de vida de uma variável local vai do ponto onde ela foi declarada até o fim do bloco onde ela foi declarada. Mas o que é um bloco? Podemos entender como bloco um trecho de código entre chaves. Pode ser um método ou um construtor:

public void m1(){
    int x = 10;
}

Ou ainda o corpo de um if, de um for etc.:

public void m1(){
    int x = 10;
    if(x >= 10){
        int y = 50;
        System.out.print(y);
    }
}

Analisando esse código, temos uma variável x, que é declarada no começo do método. Ela pode ser utilizada durante todo o corpo do método. Dentro do if, declaramos a variável y. y só pode ser utilizada dentro do corpo do if, delimitado pelas chaves. Se tentarmos usar y fora do corpo do if, teremos um erro de compilação, pois a variável saiu do seu escopo.

Tome cuidado especial com loops for. As variáveis declaradas na área de inicialização do loop só podem ser usadas no corpo do loop. O exemplo a seguir mostra a tentativa de usar uma variável cujo escopo não pode ser acessado:

for (int i = 0 , j = 0 ; i < 10 ; i++)
    j++;

System.out.println(j); //compilation error

Parâmetros de métodos também podem ser considerados variáveis locais ao método, ou seja, só podem ser usados dentro do método onde foram declarados:

class Test{
    public void m1(String s){
        System.out.print(s);
    }
    public void m2(){
        System.out.println(s); //Compilation Erro
    }
}

 

Variáveis de instância

Variáveis de instância ou variáveis de objeto são os atributos dos objetos. São declaradas dentro da classe, mas fora de qualquer método ou construtor. Podem ser acessadas por qualquer membro da classe e ficam em escopo enquanto o objeto existir:

class Person{
    String name; //instance or object variable

    public void setName(String n){
        this.name = n;
    }
}

 

Variáveis estáticas (class variables)

Podemos declarar variáveis que são compartilhadas por todas as instâncias de uma classe usando a palavra chave static. Essas variáveis estão no escopo da classe, e lá ficarão enquanto a classe estiver carregada na memória (enquanto o programa estiver rodando, na grande maioria dos casos). O código a seguir define uma variável estática:

class Person{
    static int count = 10;
}

No caso de variáveis static, não precisamos ter uma referência para usá-las e podemos acessá-las diretamente a partir da classe, desde que respeitando as regras de visibilidade da variável. O código a seguir mostra o acesso a mesma variável através da referência de uma instância e a referência da classe.

class Person{
    static int id = 20;
}

class Test{
    public static void main(String[] args){
        Person p = new Person();
        System.out.println(p.id); // instance reference acess
        System.out.println(Person.id); // classe reference acess
    }
}

Uma vez que variáveis estáticas podem ser acessadas dessas duas maneiras, tome cuidado com nomes enganosos de suas variáveis, como o caso do id acima.

 

Variáveis com o mesmo nome

Logicamente, não é possível declarar duas variáveis no mesmo escopo com o mesmo nome:

public void method(){
    int a = 0;
    int a = 10; // compile error
}

Mas, eventualmente, podemos ter variáveis em escopos diferentes que podem ser declaradas com o mesmo nome. Em casos em que possa haver ambiguidade na hora de declará-las, o próprio compilador irá emitir um erro evitando a confusão. Por exemplo, não podemos declarar variáveis de classe e de instância com o mesmo nome:

class Bla{
    static int a;
    int a; // compile error
}
...

System.out.print(new Bla().a); // Qual?!

Se a definição da classe Bla compilasse, o compilador ficaria perdido em qual das duas referências estamos tentando utilizar. A decisão dos criadores da linguagem foi que variável estática e de instância não podem ter o mesmo nome, portanto erro de compilação.

Também não podemos declarar variáveis locais com o mesmo nome de parâmetros:

public void method(String par){
    int par = 0; // compilation error
    System.out.print(par); // which one?
}

Apesar de parecer estranho, é permitido declarar variáveis locais ou parâmetros com o mesmo nome de variáveis de instância ou de classe. Essa técnica é chamada de shadowing. Nesses casos, é possível resolver a ambiguidade: para variáveis de classe, podemos referenciar pela própria classe; para variáveis de instância, usamos a palavra chave this:

class Person{
    static int x = 0;
    int y = 0;

    public static void setX(int x){
        Person.x = x; // type (class) explicit access
    }

    public void setY(int y){
        this.y = y; //  instanve (this) explicit access
    }
}

Quando não usamos o this ou o nome da classe para usar a variável, o compilador sempre utilizará a variável de “menor” escopo:

class X{
    int a = 100;

    public void method(){
        int a = 200; // shadowing
        System.out.println(a); // 200
    }
}


Exercícios

1) Escolha a opção adequada ao tentar compilar e rodar o código a seguir:

class Teste{
    public static void main(String[] args){
        for(int i = 0 ; i < 20 ; i ++){
            System.out.println(i);
        }
        System.out.println(i);
    }
}

a) Erro de compilação.

b) Compila e roda, imprimindo de 0 até 19 e depois 19.

c) Compila e roda, imprimindo de 0 até 19, depois ocorre um erro de execução.


 

2) Escolha a opção adequada ao tentar compilar e rodar o código a seguir:

class Test{
    public static void main(String[] args){
        for(int i = 0 ; i < 20 ; i++)
            System.out.println(i);
            System.out.println(i);
            System.out.println("finished");
    }
}

a) Erro de compilação.

b) Compila e roda, imprimindo de 0 até 19 e depois 19.

c) Compila e roda, imprimindo de 0 até 19, depois 19, depois finished.

d) Compila e roda, imprimindo de 0 até 19, depois ocorre um erro de execução.


3) Escolha a opção adequada ao tentar compilar e rodar o código a seguir:

class Test{
    public static void main(String[] args){
        for(int i = 0; i < 20; i++){
            System.out.println(i);
        }
        int i = 15;
        System.out.println(i);
    }
}

a) Erro de compilação na linha 6. A variável i não pode ser redeclarada.

b) Erro de compilação na linha 7. A variável i é ambígua.

c) Compila e roda, imprimindo de 0 até 19 e depois 15.

d) Compila e roda, imprimindo de 0 até 19, depois ocorre um erro de execução na linha 6.

e) Compila e roda, imprimindo de 0 até 19 e depois 19 novamente.


4) Escolha a opção adequada ao tentar compilar e rodar o código a seguir:

class Test{
    static int x = 15;
    public static void main(String[] x){
        x = 200;
        System.out.println(x);
    }
}

a) O código compila e roda, imprimindo 200.

b) O código compila e roda, imprimindo 15.

c) O código não compila.

d) O código compila mas dá erro em execução.


 

5) Escolha a opção adequada ao tentar compilar e rodar o código a seguir:

class Test{
    static int i = 3;
    public static void main(String[] a){
        for(new Test().i = 10 ; new Test().i < 100 ; new Test().i++){
            System.out.println(i);
        }
    }
}

a) Não compila a linha 4.

b) Não compila a linha 5.

c) Compila e imprime 100 vezes o número 3.

d) Compila e imprime os números de 10 até 99.

 

 


Guia Certificação JAVA OCA 8 | O Básico de JAVA | Defina o escopo de variáveis

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.