Acesso a atributos via Reflection

Com reflection podemos utilizar a sintaxe objeto.getClass().getDeclaredFields(); para pegar todos os fields de um objeto.
Mas tenho a seguinte situacao.

public class Principal {
    public String valor;
    public Composicao comp;
}

public class Composicao {
    public String nome;
}

Como assesar o atributo nome do atributo comp a partir de um objeto principal?

Não é por nada não, mas se é tudo public, qual a dificuldade?

Uma forma bem simplificada de fazer isso é sobrescrever o metodo toString() da classe Composicao e monstrar o nome.
Outra forma é ao obter o Field fazer um instanceof e ver se é uma instancia de Composicao e ai iterar novamente sobres seus fields.

Dica: para atributos privados utilize:

field.setAccessible( true );
Class<Principal> clazz = Principal.class;
Field valor = clazz.getField("valor");//Caso for public.. getField retorna um campo publico e procura na hierarquia
Field valor = clazz.getDeclaredField("valor");//getDeclaredField procura campos privates também mas apenas na classe não procura na hierarquia.
valor.setAcessible(true);//Caso for private garante acessibilidade
Principal p = new Principal();
p.valor = "xxx";
System.out.println(valor.get(p));//Aqui vemos xxx

Voce só precisa usar ou o getField ou getDeclaredField coloquei os dois para voce ver a diferença.

Pois é… nesse caso reflection não parece apropriado.

Agradeco as respostas, mas vamos la.
Minha ideia e a seguinte:

  • Construir um metodo que receba um Object e percorra todos os seus atributos para realizar operacoes de acordo com minha necessidade. (ate aqui tudo bem). O codigo esta abaixo.
  • Se eu chamo o metodo passando um objeto Principal - transformByReflection(principal) - o metodo abaixo ira encontrar os fields valor e comp. Porem (como e de se prever) ele nao percorre os atributos do objeto comp:Composicao.
  • Pensei em utilizar recursividade, porem nao encontrei qual seria a condicao de parada.

Alguma ideia? Meu metodo esta abaixo.

    public static void transformByReflection(Object objeto) {
        Field[] fields = objeto.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (field.getType().equals(String.class)) {
                try {
                    field.setAccessible(true);
                    if (field.get(objeto) != null) {
                        field.set(objeto, "Este e uma string");
                    }
                } catch (IllegalArgumentException ex) {
                    Logger.getLogger(StringTransform.class.getName()).log(Level.SEVERE, "Erro na passagem de argumentos", ex);
                } catch (IllegalAccessException ex) {
                    Logger.getLogger(StringTransform.class.getName()).log(Level.SEVERE, "Erro ao acessar os atributos do objeto", ex);
                }
            }
        }
    }

Mesmo com getField voce nao consegueria os campos de Composicao pois não é hierarquia apenas um objeto.

A condição de parada seria quando todas as classes forem percorridas e o resto dos objetos forem apenas Object, String, e objetos primitivos.