Простое правило - не обращаться прямо или косвенно к объекту "this" из конструктора.
Это означает, что вы не должны вызывать переопределяемые методы из конструктора, а также не должны вызывать метод, который вызывает переопределяемый метод, или вызывать метод, который вызывает метод, который вызывает переопределяемый метод, или ... вы понимаете это.
Это также означает, что вы не должны передавать «this» чему-либо, поскольку другая вещь может вызвать переопределяемый метод.
В вашем конкретном случае то, что у вас есть, хорошо. Если это изменится на:
class Bar extends Foo
{
public Bar () {
super (doSmth(this));
...
}
private static String doSmth (Bar bar) {
//what I can NOT do here?
}
}
Тогда у вас будет (потенциальная) проблема, потому что doSmth может вызвать переопределенный метод в подклассе Bar, который использует данные, которые еще не были инициализированы.
Вот пример того, что может произойти:
public class Main
{
public static void main(final String[] argv)
{
final A a;
a = new B();
a.foo();
}
}
abstract class A
{
protected A()
{
bar(this);
}
private static void bar(final A a)
{
a.foo();
}
public abstract void foo();
}
class B extends A
{
final String str;
public B()
{
super();
str = "Hello, World!";
}
public void foo()
{
System.out.println("str - " + str);
}
}
Итак, пока вы не вызываете переопределенные методы, вы хороши. Однако безопаснее всего просто следовать «правилу» - никогда не передавать это за пределы конструктора и никогда не вызывать переопределяемые (не финальные) методы, прямо или косвенно из конструктора.