Это работает, что вы можете увидеть, если попробуете сами. Обычно лучше избегать циклических ссылок, поскольку они усложняют дизайн.
Легко вызывать бесконечные циклы в вашем коде, если вы не будете осторожны. Например, если вы вызовете конструктор другого класса с обеих сторон, он будет прекрасно скомпилирован, но закончится java.lang.StackOverflowError; то же самое с любой (комбинацией) вызовов, которые идут туда и обратно, прямо или косвенно.
Я немного расширил ваш пример, чтобы продемонстрировать, что вы можете скомпилировать и запустить его просто отлично.
package com;
public class A {
private B b;
public A() {
b = new B();
}
public static void main(String... args) {
(new A()).print();
}
public void print() {
System.out.println(b.getText());
}
}
package com;
public class B {
private A a;
public B() {
//a = new A();
}
public String getText() {
return "Hello, world";
}
}