Analisaremos as desvantagens e vantagens das classes internas e observaremos as mais diversas sintaxes. Essas classes internas podem ser utilizadas em opções bem específicas, como a parte de tratamento de eventos com classes da package javax.swing. Porém, este pacote citado anteriormente não é requerido no exame.

Nesse artigo também será apresentado como trabalhar com datas. A API Java nos fornece um conjunto vasto de classes para auxiliá-lo a trabalhar com datas, moedas e números. O exame avaliará o seu conhecimento das classes e métodos básicos que são úteis para uso de datas.

Ao término deste artigo, teremos uma base sólida em tarefas como criar novos objetos DateFormat e Date, converter Dates em Strings e vice-versa.

Classes Internas

As classes devem ser amplamente especializadas e independentes umas das outras. Esse é um dos princípios OO, o da alta coesão. Um benefício essencial da classe interna é a relação especial que a instância de uma classe interna possui com uma instância da classe externa.

O único modo de conseguir acesso à classe interna é por meio de uma instância ativa da classe externa. Ou seja, somente em tempo de execução é que poderá ser criada uma instância da classe interna.


        package devmedia;
        public class Externa {
        private int x = 8;
        public void criarClasseInterna(){
        Interna interna = new Interna();
        interna.enxergarExterna();

        }
        class Interna {
        public void enxergarExterna() {
        System.out.println(“O atributo externo (private) x é: ” + x);
        }
        }
        public static void main(String args[ ]){
        Externa ex = new Externa();
        ex.criarClasseInterna();
        }
        }
        

Veja que a classe interna acessa diretamente um atributo private da classe externa. Isso pode ser feito, pois a classe interna é um membro da própria classe externa.

Ter domínio sobre essa sintaxe é essencial para o exame. Apresentamos a sintaxe mais simples antes, pois se entendermos essa forma de instanciar classes internas, tudo fica mais fácil. A seguir observe um exemplo, um pouco mais complexo, mas de melhor compreensão:


        Externa.Interna ceci = new Externa().new Interna();
        

Sendo assim:


        package devmedia;
        class A{
        class B{}
        }
        public class C{
        public static void main(String args[ ]){
        A a = new A();
        A.B xy = a.new B();
        }
        }
        

Relação de this com Classes Interna e Externa

Como um objeto referencia ele próprio? Normalmente, por meio do uso da referência this. A palavra-chave this pode ser utilizada no código da instância.

No exemplo seguinte você pode ver como acessar um atributo de uma classe externa de dentro de uma classe interna. O que pode ser feito através do uso da referência this.


        package devmedia;
        public class X{
        private int x = 10;
        public String toString(){
        return “externa”;
        }
        class Y{
        public void acessar(){
        System.out.println(“A classe interna” + this);
        System.out.println(“A classe externa” + X.this.x);
        }
        public String toString(){
        return “interna”;
        }
        }
        public static void main(String args[ ]){
        X.Y xy = new X().new Y();
        xy.acessar();
        }
        }
        

A classe interna é um membro da classe externa, assim como os métodos e atributos, resumindo, os modificadores (final, private, abstract, public, protected, strictfp e static) podem ser utilizados em uma classe interna.

Classes Internas Locais de Métodos


        package devmedia;
        class Global {
        private String x = “Global - Externa”;
        void executar(){
        class Interna {
        public void acessarGlobal(){
        System.out.println(“Atributo (private) x, da classe externa: ” + x);
        } //finaliza método da classe interna
        } //finaliza classe interna
        Interna i = new Interna();
        i.acessarGlobal();
        } //finaliza método da classe externa
        } // finaliza classe externa
        public class Executavel{
        public static void main(String args[ ]){
        Global e = new Global();
        e.executar();
        }
        }
        

Somente dentro do método que foi definida é que a classe interna local de método será instanciada. A referência da classe interna local de método possuirá um relacionamento especial com o objeto da classe que o estiver encapsulando, assim como objetos da classe interna comum. Porém, o objeto da classe interna não enxergará variáveis locais de método onde a classe interna for declarada.

As variáveis locais do método residem na pilha e somente existem segundo a duração do método. Já sabemos que o escopo de uma variável local é limitado ao método em que foi definida.

Quando o método termina sua execução, o quadro da pilha é retirado, assim como sua variável. No entanto, mesmo após a conclusão do método, o objeto da classe interna criado dentro dele pode ainda estar ativo no heap - e se uma referência a ele tenha sido passada a algum outro trecho de código e, logo após, armazenada em uma variável de instância?

Já que as variáveis locais não têm garantia de seguirem ativas por tanto tempo quanto o objeto da classe interna local de método, esse objeto não pode utilizá-las. A não ser que as variáveis locais sejam marcadas como final, pois neste caso, ela não será alterada.

O código seguinte tenta ter acesso a uma variável local final dentro de um método de uma classe interna local de método, isso é possível somente porque a variável local é final.


        package devmedia;
        class ClasseExterna {
        private String x = “externa”;
        void acao(){
        final int variavelLocal = 11;
        class Interna {
        public void acessaExterna(){
        System.out.println(“x, de ClasseExterna: ” + x);
        System.out.println(“variável local do método acao(): ” + variavelLocal);
        } //finaliza método da classe interna
        } //finaliza classe interna
        Interna in = new Interna();
        in.acessaExterna();
        } //finaliza método da classe externa
        } //finaliza classe externa
        public class TesteMain{
        public static void main(String args[ ]){
        ClasseExterna e = ClasseExterna();
        e.acao();
        }
        }
        

Classes Internas Anônimas

Apresentaremos a seguir a sintaxe menos comum que você verá em Java: classes internas declaradas sem nome, daí a palavra anônima. E como se não fosse estranho o suficiente, você poderá até definir essas classes, não só dentro de um método, mas no argumento de um método.


        package devmedia;
        class Funcionario{
        public int getSetor(){
        return 1;
        }
        }
        class Chefe{
        Funcionario e = new Funcionario(){
        public int getSetor(){
        return 100;
        }
        };
        }
        

O polimorfismo se faz presente quando classes internas anônimas estão envolvidas. Vale lembrar que, como no exemplo anterior, utilizamos o tipo de variável de referência da superclasse para referenciar um objeto da subclasse.

Para o exame, é preciso ser capaz de identificar uma classe interna anônima que, ao invés de sobrescrever um método da superclasse, defina seu método novo.

Do mesmo modo que houve uma sobrescrição envolvendo as classes Funcionario e Chefe, em relação ao método getSetor(), como em uma relação de herança, poderia ter acontecido uma sobrescrição envolvendo interfaces. Veja o exemplo abaixo:


        package devmedia;
        interface Pagamento{
        String receberPagamento();
        }
        class Funcionario{
        Pagamento pg = new Pagamento(){
        public String receberPagamento(){
        return “Funcionario recebendo pagamento”;
        }
        };
        }
        class Chefe{
        Pagamento pg = new Pagamento(){
        public String receberPagamento(){
        return “Chefe recebendo pagamento”;
        }
        };
        }
        public class Anonima{
        public static void main(String args[ ]){
        Funcionario e = new Funcionario();
        System.out.println(e.pg.receberPagamento());
        Chefe boss = new Chefe();
        System.out.println(boss.pg.receberPagamento());
        }
        }
        

Mais uma coisa a ser memorizada sobre implementadores anônimos de interface: eles podem implementar apenas uma interface. Simplesmente não existe um mecanismo que defina que sua classe interna implementará diversas interfaces. Na realidade, uma classe interna anônima não pode nem estender uma classe e implementar uma interface ao mesmo tempo.

Classes Estáticas Aninhadas

Conhecidas como classes aninhadas de nível superior ou de classes internas estáticas. Uma classe aninhada estática é aquela que é um membro estático da classe encapsuladora, conforme é demonstrado no exemplo a seguir.


        package devmedia;
        class X {
        static class Y{ }
        }
        

A classe propriamente dita não é realmente estática; não há classes estáticas. O modificador static, nessa situação, informa que a classe aninhada é um membro estático da classe externa. Isso quer dizer que ela pode ser acessada como qualquer membro estático, sem ter necessariamente uma instância da classe externa.


        package devmedia;
        public class X{
        static class Y{
        void impressao(){
        System.out.println(“classe estática”);
        }
        }
        public static void main(String args[ ]){
        Y y = new Y(); //independe da classe encapsuladora
        y.impressao();
        X.Y x = new X.Y();
        x.impressao();
        new X.Y().impressao();
        }
        }
        

A primeira maneira de instanciação da classe estática demonstra a total independência da classe externa. As outras duas formas funcionam a partir de qualquer lugar visível.

Datas

Quando trabalhamos com datas do mundo todo, precisamos nos familiarizar com pelo menos quatro classes dos pacotes java.util e java.text. Na realidade, admitiremos de que você poderá encontrar algumas perguntas no exame que utilizem classes que não foram citadas nos objetivos da Sun (Oracle). Eis as cinco classes relacionadas a datas que você precisará compreender para o exame:

  • java.util.Date: A maioria dos métodos desta classe foram depreciados, mas poderemos usá-la como uma ponte entre as classes DateFormat e Calendar. Uma instância de Date representa uma hora e data mutáveis, até a resolução de milissegundos.
  • java.util.Calendar:Esta classe nos fornece uma ampla variedade de métodos que auxiliam a conversão e manipulação de datas e horas. Por exemplo, caso queira acrescentar um mês a uma determinada data, ou descobrir em que dia da semana vai cair primeiro de janeiro de 2500, os métodos da classe Calendar estão aí para facilitar isso.
  • java.text.DateFormat: Esta classe é utilizada para formatar datas não apenas fornecendo diversos estilos como “01/11/2007” ou “Março, 1, 2017”, bem como para formatar datas para vários locais do mundo.
  • java.text.NumberFormat: Esta classe é usada para formatação de números e moedas para todos os locais do mundo.
  • java.util.Locale: Esta classe é utilizada juntamente com NumberFormat e DateFormat para formatar número, datas e moedas para locais específicos. Com o auxílio da classe Locale, você poderá converter uma data como “09/10/2005” para “Terça, 9 de outubro de 2005”. Caso queira manipular datas sem produzir output formatado, você poderá utilizar Locale diretamente com Calendar.

Combinando Classes Relacionadas a Datas e Números

A tabela seguinte fornece uma visão mais geral de casos comuns de uso relacionados a números e datas.

Casos de Uso Etapas
Obter a hora e data atuais.

Date data = new Date();

String aux = data.toString();

Obter um objeto que lhe permita realizar cálculos de data e hora no seu local (Locale).

Calendar c = Calendar.getInstance();

c.add(10, 10);

Obter um objeto que permita a realização de cálculos de data e hora em locais diferentes.

Locale locale = new Locale(“Portuguese”);

Calendar cal = Calendar.getInstance(locale);

cal.add(150, 150);

Obter um objeto que lhe permita realizar cálculos de hora e data e depois formatar o resultado em diferentes locais, com diversos estilos de datas.

Calendar cal = Calendar.getInstance();

Locale loc = new Locale(“English”);

Date data = cal.getTime();

DateFormat df = DateFormat.getDateInstance(style, loc);

String aux = df.format(data);

Obter um objeto que formate números ou moedas em vários locais.

Crie um Locale para cada local.

Crie um NumberFormat NumberFormat nf = NumberFormat.getInstance(loc); OU NumberFormat nf =

NumberFormat.getCurrentInstance(loc);

String aux = nf.format(numeroQualquer);

Classe Date

A classe Date está no exame por muitas razões: poderemos achá-la em códigos antigos, ela é de fácil utilização caso você queira a data e hora atuais, é bastante útil quando se quer uma hora universal que não seja afetada por fusos horários e, por fim, você a utilizará como uma ponte temporária para formatar um objeto Calendar com o uso da classe DateFormat. Conforme mencionado anteriormente, uma instância da classe Date representa uma só data e uma só hora. Internamente, hora e data são armazenadas como um tipo long primitivo.

Classe Calendar

A classe Calendar foi criada para tornar essa manipulação de datas mais simples. Embora a classe Calendar tenha muitos atributos e métodos. Após você pegar o jeito de algumas delas, as outras tendem a fluir de modo parecido. Ao tentar utilizar a classe Calendar uma primeira vez, você notará que ela é uma classe abstrata e, evidentemente, não podemos instanciá-la. Para usar uma instância de Calendar, precisamos de um dos métodos estáticos sobrecarregados getInstance():


        Calendar calendar = Calendar. getInstance();
        

É essencial saber que qualquer manipulação de datas usando Calendar, que é bem mais interessante, siga atentamente quatro passos. O primeiro passo consiste na criação de Date. Em seguida, uma referência Calendar é adquirida. Depois, a referência Date é encapsulada em um Calendar (setTime()). Após isso, a manipulação pode ser efetuada. Uma vez feito esse processo, pode-se passar a referência Calendar para uma Date (Date aux = cal.getTime()) e mostrar os resultados.


        package devmedia;
        import java.util.*;
        public class DataTeste {
        public static void main(String args[ ]) {
        //exibe a hora atual - adicionando dois meses
        Date d1 = new Date();
        System.out.println(d1);
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(d1);
        cal1.add(Calendar.DAY_OF_MONTH, 2);
        Date d2 = cal1.getTime();
        System.out.println(d2);

        //baseado na hora atual, adiciona 5 horas
        Date d3 = new Date();
        System.out.println(d3);
        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(d3);
        cal2.add(Calendar.HOUR, 5);
        Date d4 = cal2.getTime();
        System.out.println(d4);

        //baseado na hora atual, adiciona 11 minutos
        Date d5 = new Date();
        Calendar c = Calendar.getInstance();
        c.setTime(d5);
        c.add(Calendar.MINUTE, 11);
        Date d6 = c.getTime();
        System.out.println(d6);

        //baseado na hora atual, adiciona 3 segundos
        Date d7 = new Date();
        Calendar c1 = Calendar.getInstance();
        c1.setTime(d7);
        c1.add(Calendar.MILLISECOND, 3000);
        Date d8 = c1.getTime();
        System.out.println(d8);
        }
        }
        

Date Format

Após a etapa de manipular e criar datas, iremos ver como formatá-las. Eis um exemplo de como uma data pode ser formatada de vários modos.


        import java.util.*;
        import java.text.*;
        public class DataMain {
        public static void main(String args[ ]) {
        Date date1 = new Date();
        DateFormat [ ] dfa = new DateFormat[6];
        dfa[0] = DateFormat.getInstance();
        dfa[1] = DateFormat.getDateInstance();

        dfa[2] = DateFormat.getDateInstance(DateFormat.SHORT);
        dfa[3] = DateFormat.getDateInstance(DateFormat.MEDIUM);
        dfa[4] = DateFormat.getDateInstance(DateFormat.LONG);
        dfa[5] = DateFormat.getDateInstance(DateFormat.FULL);

        for (DateFormat dateFormat : dfa)

        System.out.println(dateFormat.format(date1));

        }

        }
        

Saída console:
03/10/10 13:43
03/10/2010
03/10/10
03/10/2010
3 de Outubro de 2010
Domingo, 3 de Outubro de 2010

No primeiro momento, parece que DateFormat é uma classe abstrata, sendo assim não podemos usar new para instanciar DateFormat. Então, nesse caso, utilizamos dois métodos de fábrica (Factory), getDateInstance() e getInstance(). Note que getDateInstance() está sobrecarregado; quando abordarmos os Locales, veremos a outra versão de getDateInstance(), que será necessário conhecer para o exame.

Nessa situação, a versão sem argumentos de getDateInstance() fornece o mesmo estilo da versão MEDIUM do método, porém essa não é uma regra geral. Trataremos mais sobre esse assunto quando vermos Locales. Por último, usamos o método format() para criar Strings representando as versões formatadas da Date com que estamos trabalhando. Um método importante com o qual é necessário se familiarizar é parse(). Esse método parse() usa uma String formatada no estilo da instância de DateFormat sendo utilizada e converte a String em um Date.


        import java.util.*;
        import java.text.*;
        public class DataMain2 {
        public static void main(String args[ ]) {
        Date d1 = new Date();
        System.out.println(d1);
        DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);

        String s = df.format(d1);

        System.out.println(s);


        try {

        Date date2 = df.parse(s);

        System.out.println(“Data depois do parse: ” + date2);

        }

        catch (ParseException pe) {

        System.out.println(“Exceção de parsing”);

        }

        }
        }
        

Saída console:
Sun Oct 03 14:05:59 GMT 2010
03/10/08
Data depois do parse: Fri Oct 03 00:00:00 GMT 2010

Note que, pelo fato de utilizarmos o estilo SHORT, perdemos um pouco de precisão quando convertemos o Date em uma String. Essa perda de precisão surgiu quando convertemos de volta para o objeto Date, e a hora passou de 14:05:59 para 00:00:00

Locale

Antes, falamos que uma das principais razões para a existência desse artigo era testar sua capacidade de realizar algumas tarefas de internacionalização. Essa espera terminou: a classe Locale é a sua passagem para a dominar o mundo.

Tanto a classe NumberFormat quanto a classe DateFormat podem utilizar uma instância de Locale para customizar uma saída formatada, para que se adapte a qualquer local. Os dois construtores de Locale que você precisa conhecer para o exame são:

  • Locale(String idioma, String pais)
  • Locale(String idioma)

O parâmetro idioma representa um Código de Linguagem ISO 639, dessa maneira se quisermos formatar as suas datas ou números em Italiano, por exemplo, teria que ser usado “it” para o argumento idioma.

Há mais de 500 códigos ISO existentes. Por isso, fique calmo, não será necessário que você memorize nenhum Código de Linguagem ISO, nem código de países ISO, que são aproximadamente 240, para a prova.

Lembre que tanto os objetos NumberFormat quanto os DateFormat podem ter seus locais definidos apenas no instante da instanciação. Atenção com códigos que tentem alterar o local em uma instância que já existe. Não existe nenhum método que faça isso.

Há alguns outros métodos em Locale, são eles: getDisplayCountry() e getDisplayLanguage(), que será necessário conhecer para a prova da certificação. Esses métodos permitem a criação de Strings que representem o país e o idioma de um local, em termos tanto do local padrão (default) quanto de qualquer outro local.


        package devmedia;
        import java.util.*;
        import java.text.*;
        public class DataMain3 {
        public static void main(String args[ ]) {
        Calendar cal = Calendar.getInstance();
        cal.set(2010, 11, 14); //14 de dezembro de 2010 > A contagem começa em 0
        Date d1 = cal.getTime();

        Locale l1 = new Locale(“it”, “IT”); //Itália
        Locale l2 = new Locale(“pt”, “BR”); //Brasil
        Locale l3 = new Locale(“da”, “DK”); //Dinamarca

        System.out.println(“país: ” + l1.getDisplayCountry());
        System.out.println(“país: ” + l2.getDisplayCountry());
        System.out.println(“país: ” + l3.getDisplayCountry());
        System.out.println(“idioma ” + l3.getDisplayLanguage()); //Inglês
        System.out.println(“idioma ” + l3.getDisplayLanguage(l3)); //Dinamarquês
        System.out.println(“idioma ” + l1.getDisplayLanguage());
        System.out.println(“idioma ” + l1.getDisplayLanguage(l1));
        }
        }
        

Saída:
país: Italy
país: Brasil
país: Denmark
idioma Danish
idioma dansk
idioma Italian
idioma italiano

Classe NumberFormat

Terminaremos a parte teórica desse artigo falando da classe NumberFormat. Assim como DateFormat, NumberFormat é uma classe abstrata, de modo que será usado alguma versão de getInstance() ou de getCurrencyInstance() para instanciar um objeto NumberFormat.


        import java.text.*;
        public class FormatandoNumeros {
        public static void main(String args[ ]) {
        float fl1 = 234.567f;
        NumberFormat nf = NumberFormat.getInstance();

        System.out.print(nf.getMaximumFractionDigits() + “ “);
        System.out.print(nf.format(fl1) + “ “);

        nf.setMaximumFractionDigits(2);
        System.out.print(nf.format(fl1)) + “ “);
        }
        }
        

Saída console:
3
234,567
234,57

Perceba que, nesta situação, o número inicial de dígitos fracionários para o NumberFormat padrão é de 3 e o método format() arredonda o valor, no lugar de simplesmente descartar as casas decimais que excedem. Após a modificação dos dígitos fracionários de nf, o valor inteiro de fl1 é exibido.

Mini-teste

  1. Analise o seguinte trecho de código:
    
                    package devmedia;
                    class H{
                    static void instanciarEstatico(){}
                    void blablabla(){ instanciarEstatico();}
                    }
                    

    O que ocorrerá?

    1. Será lançada uma exceção.
    2. O código compilará e executará sem problemas.
    3. O código apresentará erro de compilação.
  2. Dado o seguinte trecho de código:
    
                    package devmedia;
                    class A{
                    int a = 15;
                    class B{
                    int a = 20;
                    void mostrar(){
                    System.out.print(this.a + A.this.a);
                    }
                    }
                    }
                    public class ExternaMain{
                    public static void main(String args[ ]){
                    new A().new B().exibir();
                    }
                    }
                    

    Qual das alternativas a seguir representa a saída do código acima?

    1. 10
    2. 20
    3. 35
    4. Será lançada uma exceção.
    5. O código não compilará.
  3. Observe o código abaixo:
    
                    package devmedia;
                    class A{
                    String s = “Java”;
                    void fazer(){
                    int y = 11;
                    class B{
                    void mostrar(){
                    System.out.println(y);
                    }
                    }
                    }
                    }
                    

    Qual das alternativas a seguir representa a saída do código acima?

    1. O código não compilará.
    2. Será lançada uma exceção
    3. O código executará, mas nada será exibido.
    4. Java.
  4. Analise o código a seguir:
    
                    package devmedia;
                    class X{
                    X(){
                    System.out.print(“X”);
                    }
                    }
                    class Y{
                    Y(){
                    System.out.print(“Y”);
                    }
                    X x = new X(){};
                    public class TesteMain{
                    public static void main(String args[ ]){
                    Y y = new Y();
                    }
                    }
                    

    Qual das alternativas a seguir representa a saída do código acima?

    1. XY
    2. YX
    3. X
    4. Y
  5. Avalie o seguinte trecho de código:
    
                    package devmedia;
                    class A{
                    static String s = “JavaDevmedia”;
                    static class B{
                    B a = new B(); //comentário 1
                    }
                    B b = new B(); //comentário 2
                    }
                    class TesteMain{
                    A.B c = new A.B(); //comentário 3
                    }
                    

    Qual(is) da(s) alternativa(s) a seguir pode(m) ser marcada(s) como correta(s)?

    1. O código não compilará.
    2. O código não executará.
    3. A instrução com comentário 1 está correta.
    4. A instrução com comentário 2 está correta.
    5. A instrução com comentário 3 está correta.
  6. Avalie o código abaixo:
    
                    package devmedia;
                    import java.util.*;
                    import java.text.*;
                    public class X {
                    public static void main(String args[ ]){
                    Calendar c = Calendar.getInstance();
                    c.set(2010, 11, 4);
                    Date d1 = c.getTime();
                    DateFormat d = new DateFormat(DateFormat.SHORT);
                    System.out.println(df.format(d1));
                    }
                    }
                    

    O que acontecerá?

    1. O programa não compilará.
    2. Será lançada uma exceção.
    3. Será exibida a data 04/11/2010
    4. Será exibida a data 04/12/2010
  7. Analise o seguinte trecho de código:
    
                    package devmedia;
                    import java.util.*;
                    import java.text.*;
                    public class Main {
                    public static void main(String args[ ]){
                    Date date1 = new Date();
                    ClasseA a = DateFormat.getDateInstance(DateFormat.SHORT);
                    ClasseX x = a.format(date1);
                    try{
                    ClasseY y = a.parse(x);
                    }
                    catch(ParseException p)
                    {
                    p.printStackTrace();
                    }
                    }
                    

    O que deve ser colocado, respectivamente, no lugar de ClasseA, ClasseX e ClasseY?

    1. DateFormat String Date
    2. java.util.DateFormat java.lang.String java.util.Date
    3. Date String Date
    4. DateFormat Date String
    5. DateFormat Long String
  8. Quais das alternativas a seguir são verdadeiras?
    1. A classe Calendar pode ser instanciada diretamente.
    2. DateFormat.getDate() é utilizado para converter uma String em uma instância de Date.
    3. Tanto objetos DateFormat quanto NumberFormat podem ser instanciados para ser específicos de um Locale.
    4. Tanto objetos Currency quanto NumberFormat devem ser criados por meio de métodos estáticos.
    5. Caso um Locale de uma instância seja diferente do atual, ele deve ser especificado na hora da criação.
    6. Uma mesma instância de NumberFormat pode ser utilizada para criar objetos Number a partir de Strings e para criar números formatados a partir de números.

Gabarito comentado

  1. Resposta correta: B

    Não há problemas em um método estático ter acesso a um método de instância, porém a recíproca não é verdadeira. Portanto, esse código executará e compilará sem problema algum. Observe que o método instanciarEstatico() é um método estático e o método blablabla() é um método de instância. Sendo assim, o método instanciarEstatico() pode acessar o método blablabla() normalmente.

  2. Resposta correta: C

    O modo de instanciação da classe interna está correto. Logo, a maneira de se invocação do método mostrar() também está correta. O código do método mostrar() não apresenta nem falhas semânticas, nem sintáticas; sendo assim, o código é compilado. Nenhuma exceção é lançada.

    A parte que merece maior atenção nessa questão é a utilização da referência this. Ela pode ser utilizada diretamente na classe interna e, nessa situação, estamos nos referindo a uma instância da classe interna, ou, por meio da prefixação, usando o nome da classe externa, estamos nos referindo a uma instância da classe externa. Desse modo, a soma acontece sem problemas e o resultado é 35.

  3. Resposta correta: A

    As variáveis locais do método ficam na pilha e apenas existem conforme a duração do método. Já temos noção que o escopo de uma variável local é limitado ao método em que foi criada.

    Quando o método é terminado, o quadro da pilha é eliminado e a variável deixa de existir. Entretanto, mesmo depois que o método é finalizado, o objeto da classe interna criado dentro dele ainda pode estar ativo na pilha. E se uma referência a ele tenha sido transmitida a algum outro código e, em depois, guardada em uma variável de instância?

    Já que as variáveis locais não têm como garantir a continuação como ativas por tanto tempo quanto o objeto da classe interna local de método, esse objeto não pode utilizá-las. A não ser que as variáveis locais sejam especificadas como final, pois nesse caso, ela não será alterada.

  4. Resposta correta: A

    De forma implicita, a classe Y estende a classe X. Quando uma instância Y é criada, seu construtor é chamado. Esse construtor faz uma invocação implícita a super(). Assim, no primeiro momento, a saída X é mostrada e, na sequência, a saída Y é exibida, formando XY.

  5. Resposta correta: C, D e E

    No contexto da classe encapsuladora A, existe a possibilidade de instanciar a classe estática aninhada B, sem problema algum. Está correta também a sintaxe apresentada na linha que possui o comentário 3. Essa é a sintaxe para se criar a classe estática de fora da classe encapsuladora.

  6. Resposta correta: A

    A classe DateFormat, como a classe Calendar, é uma classe abstrata. Então, ela não pode ser instanciada diretamente. Verifique, sempre de que isso não acontece antes de proceder na tentativa de entender a lógica do programa.

  7. Resposta correta: A

    A questão é sobre retorno de métodos. O primeiro retorno requer uma instância da classe DateFormat, o segundo exige uma instância da classe String, já o terceiro espera um retorno de um objeto da classe Date. É válido observar que a classe DateFormat faz parte do pacote java.text, diferentemente da classe Date, que pertence ao pacote java.util. Não existe nada de mais em se qualificar uma classe com todo seu nome, desde que isso seja realizado de modo correto.

  8. Resposta correta: C, D, E e F

    A primeira declaração é falsa, pois Calendar, assim como NumberFormat, Currency e DateFormat, são abstratas e não podem, obviamente, ser instanciadas, pois a única hipótese de se obter a referência é por meio da invocação de métodos estáticos, da classe correspondente.

    Para se converter uma String em um Date, usa-se o método de instância parse(), de DateFormat. Tanto objetos DateFormat quanto NumberFormat podem ser criados por meio de métodos estáticos. Isso está correto devido ao fato de ambas as classes serem abstratas.

    Caso um Locale de uma instância seja diferente do atual, ele deve ser especificado na hora da criação. Um locale não pode ser alterado depois, ou ele deve ser especificado apenas no momento da criação.

    Uma mesma instância de NumberFormat pode ser utilizada na criação de objetos Number a partir de Strings e para criar números formatados a partir de outros números. Avalie o código abaixo:

    
                    package devmedia;
                    import java.util.*;
                    import java.text.*;
                    public class A {
                    public static void main(String args[ ]){
                    NumberFormat nf = NumberFormat.getInstance();
                    String str = nf.format(234);
                    try{
                    Number x = nf.parse(str);
                    }
                    catch(ParseException p)
                    {
                    p.printStackTrace();
                    }
                    }
                    }
                    

    Inicialmente criamos um NumberFormat>, em seguida um número é formatado para uma String e, por fim, a String, através da invocação do método de instância parse(), é transmitida a um Number.

Finalizamos assim mais esse artigo. Bons estudos!


Leia todos artigos da série