我有下一个代码:
class Foo {
public Foo (String param) { ... }
}
class Bar extends Foo {
public Bar () {
super (doSmth());
...
}
private static String doSmth () {
//what I can NOT do here?
}
}
请问安全吗? doSmth
方法有什么限制吗?
最佳答案
简单的规则是不要直接或间接地从构造函数中访问“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);
}
}
因此,只要您不调用任何重写的方法就可以了。然而,最安全的做法是遵循从不将 this 传递到构造函数之外并且从不直接或间接从构造函数调用可覆盖(非最终)方法的“规则”。
关于java - 为什么java要求构造函数的第一行要调用父构造函数?如果我们绕过这个要求,会有什么陷阱吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3160370/