加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

为什么java要求第一行构造函数应该调用父构造函数?如果我们绕过

发布时间:2020-12-15 04:52:43 所属栏目:Java 来源:网络整理
导读:我有下一个代码: 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方法有任何限制吗? 解决
我有下一个代码:

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的子类中调用一个依赖于尚未初始化的数据的override方法.

以下是可能发生的情况的示例:

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);
    }
}

所以,只要你不调用任何被覆盖的方法,你就是好的.但是,最安全的做法就是遵循“规则”,即永远不要在构造函数之外传递它,也不要直接或间接地从构造函数中调用可重写(非最终)方法.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读