Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Exportanto classe default com método público

Caros,

fiquei na dúvida sobre um código que fiz, testando um cenário onde uma classe possui um método público que retorna outra classe do mesmo pacote mas que "possui" o modificador default.

Isso não permite "exportar" uma classe para fora da visibilidade do pacote?

Segue o código produzido:

package br.com.alura;

import br.com.alura.pacote.C;

class A {
    public static void main(String[] args) {
        C c = new C();

        System.out.println(c.getB());

    }
}

package br.com.alura.pacote;

class B {

    B () {
        System.out.println("cheguei");
    }

    public int getValor() {
        return 10;
    }

    @Override
    public String toString() {
        return "Valor: " + getValor();
    }

}

package br.com.alura.pacote;

public class C {

    public B getB() {
        return new B();
    }

}

Ao executar o código acima, tenho como resposta:

cheguei
Valor: 10

Entretanto quando tento executar o código abaixo, dá erro de compilação:

package br.com.alura;

import br.com.alura.pacote.C;

class A {
    public static void main(String[] args) {
        C c = new C();

        System.out.println(c.getB().getValor());

    }
}

Erro de compilação:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
    The type B is not visible

    at br.com.alura.A.main(A.java:9)

Achei interessante que ao chamar o método toString(), foi executado o método sobrescrito da classe mas ao chamar diretamente o método getValor() deu erro de compilação, mesmo ambos sendo públicos.

Vocês podem explicar melhor este comportamento?

1 resposta
solução!

Oi Daniel, não é muito claro mesmo. O bytecode gerado pelo código que funciona é algo parecido com o que segue:

        C c = new C();

        Object b = c.getB();
        System.out.println(b.toString());

Perceba que não tentamos invocar nada que está em B, nem adicionamos nenhum import.. Até pq não podemos trabalhar com essa classe fora do seu pacote de origem. O bytecode gerado referencia o objeto através da classe Object, que é a mãe de todo mundo, e aí é permitido invocar o toString que, por polimorfismo, cai no método escrito na classe B.

É estranho, mas está certo :).