[quote=diegogmarques]Mesmo que a instância de A não esteja completamente construída quando eu inicializar B, eu vou inicializar B passando uma referência para esta instância de A. Neste caso, mesmo que eu continua construindo A depois de inicializar B, a referência continuará sendo a mesma, o que não geraria problemas, não?
[/quote]
E porque teria? O problema não está necessariamente em cruzar referências, mas na forma como isso é feito, ou seja, em passar um objeto A parcialmente construído para B, na hora de fazer isso.
Não entendi o seu exemplo. O getStr() refere-se a uma variável local, e não faz qualquer menção com a referência. O que ele tem a ver com A?
No caso, você não deve passar o this como parâmetro numa construção por causa disso aqui:
[code]
public class A {
private int a;
private String x;
private B b;
public A() {
b = new B(this);
a = 10;
x = “Vinicius”;
}
//gets e sets
}
public class B {
private int c;
public void B(A a) {
c = a.getA() * 2;
}
//gets e sets
} [/code]
Pergunta-se. Qual é o valor que método getA() retornará, quando B fizer a chamada?
A coisa pode ficar ainda pior se A tiver subclasses e B chamar um método sobrescrito de A. Por exemplo, suponha que você tenha “corrigido” a classe A, e colocado a inicialização de B na última linha. Aí fica correto, certo?
[code]
public class A {
private int a;
private String x;
private B b;
public A() {
a = 10;
x = “Vinicius”;
b = new B(this);
}
//gets e sets
}[/code]
Agora, imagine que posteriormente alguém cria a classe C, dessa forma:
[code]public class C extends A {
private int x;
public C() {
this.x = 20;
}
public void getA() {
return super.getA() * x;
}
}[/code]
O que acontece quando criamos os objetos assim?
A a = new C();
Note que agora o construtor de B irá novamente tentar chamar o método getA(). Aparentemente está tudo certo, mas o método sobrescrito precisará do valor de x, que não foi inicializado ainda, já que a construção ocorre de cima para baixo e o construtor da classe C, portanto, não foi chamado.
É uma má prática passar objeto incompleto para B, porque quem quer que programe B deve ter como pressuposto que A é um objeto válido, e completamente construído. Quando você troca referências da forma que você mostrou, esse pressuposto é inválido, o que pode gerar erros de programação difíceis de corrigir. O comportamento do Java nessas situações é indefinido.