Pergunta

Existe alguma maneira diferente usando a reflexão para acessar os membros de uma classe interna anônima?

Foi útil?

Solução

anônimos classes internas têm um tipo, mas nenhum nome.

Você pode acessar campos não definidos pela supertipo nomeado. No entanto, uma vez atribuído a uma variável do tipo de chamada, a interface está perdido.

Obviamente, você pode acessar os campos de dentro da própria classe interna. Uma maneira de adicionar o código é através de um initialiser exemplo:

final AtomicInteger y = new AtomicInteger();
new Runnable() {
    int x;
    {
        x = 5;
        doRun(this);
        y.set(x);
    }
    public void run() {
        ... blah ...
    }
};

O valor retornado pela expressão classe interna anônima tem o tipo anônimo, então você tem uma chance de usá-lo fora da própria classe:

final int y = new Runnable() {
    int x;
    {
        x = 5;
        doRun(this);
    }
    public void run() {
        ... blah ...
    }
}.x;

Você também pode passá-lo através de um método declarado semelhante a:

<T extends Runnable> T doRun(T runnable);

Outras dicas

Você pode usar classes locais de classe em vez anônimo. Look:

public class Test {
    public static void main(String... args) {
        class MyInner {
            private int value = 10;
        }

        MyInner inner = new MyInner();
        System.out.println(inner.value);
    }
}

Você pode ter referência do tipo MyInner apenas no corpo do método embora. Então, fora do método que você não será capaz de usar seus campos / métodos que não são declarados na sua super classe (java.lang.Object neste caso) ou interface.


public class AccessAnonymous {
    private Runnable runnable; // to have instance of the class

    public static void main(String[] args) throws Exception {
        AccessAnonymous a = new AccessAnonymous();
        a.a(); // init field

        Class clazz = a.runnable.getClass();
        Field field = clazz.getDeclaredField("i");
        field.setAccessible(true);

        int int1 = field.getInt(a.runnable);
        System.out.println("int1=" + int1);
    }

    public void a() {
        runnable = new Runnable() {
            private int i = 1;

            public void run() {
                i = 90;
            }

        };
        runnable.run();// change value
    }
}

No caso de classes anônimas, há também uma troca entre a desordem causada pela classe e a conveniência de ter isso de forma anônima. aulas complicadas raramente pertencem como anônimo, mas sim como o nome interior privado.

Na maioria das classes anônimas, só precisamos de conhecimento "feed" e pode fazê-lo em construção. Em algumas classes anônimas (por exemplo, veículos de valor de retorno) que também se preocupam com um valor de retorno.

Como sabemos, membros de dados não deve ser diretamente acessados, mas sim com um setter getter. Isto, se você se encontra em uma situação que você adicionou lotes de getters e setters, provavelmente você está fazendo algo errado de qualquer maneira e não deve estar usando uma classe anônima.

Se ele implementa uma interface ou estende uma classe existente, você pode acessar os membros definidos na classe interface ou base.

Mr Fooz é certo, exceto que as interfaces só pode definir membros constantes. a melhor maneira seria adicionar métodos getter / setter para sua interface e, em seguida, use-os para obter o seu valor. mas, em seguida, para cada classe anônima que você teria que definir esses métodos (um tipo de dor).

Se você quiser código legível, de fácil manutenção, não usar classes anônimas. Se você usar classes anônimas e quer código legível, de fácil manutenção, não usar classes anônimas quando você precisa acessar o elemento em que classe interna. Existem várias maneiras de fazer isso, mas peço-lhe para não usar qualquer um desses hacks. Legibilidade supera todas as outras virtudes.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top