java 具有继承的静态块的行为

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10698516/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 02:09:45  来源:igfitidea点击:

Behavior of static blocks with inheritance

javainheritancestaticstatic-block

提问by Asha

I am trying to use static blocks like this:

我正在尝试使用这样的静态块:

I have a base class called Base.java

我有一个基类叫做 Base.java

public class Base {

    static public int myVar;

}

And a derived class Derived.java:

和一个派生类Derived.java

public class Derived extends Base {

    static
    {
        Base.myVar = 10;
    }
}

My mainfunction is like this:

我的main功能是这样的:

public static void main(String[] args)  {
    System.out.println(Derived.myVar);
    System.out.println(Base.myVar);
}

This prints the out put as 0 0where as I expected 10 0. Can somebody explain this behavior? Also, if I want my derived classes to set the values for a static variable how can I achieve that?

这会0 0按照我的预期打印输出10 0。有人可以解释这种行为吗?另外,如果我希望我的派生类设置静态变量的值,我该如何实现?

采纳答案by Mikita Belahlazau

As I understand. You don't call any Derivedproperties (myVarbelongs to Base, not to Derived). And java is not running static block from Derived. If you add some static field to Derivedand access it, then java executes all static blocks.

我认为。您不调用任何Derived属性(myVar属于Base,不属于Derived)。并且 java 没有从Derived. 如果您添加一些静态字段Derived并访问它,那么 java 将执行所有静态块。

class Base {

    static public int myVar;

}


class Derived extends Base {

    static public int myVar2;

    static
    {
        Base.myVar = 10;
    }
}


public class Main {
    public static void main( String[] args ) throws Exception {
        System.out.println(Derived.myVar2);
        System.out.println(Base.myVar);
    }
}

From java specification, when class is initialized (and static block got executed):

从 java 规范,当类被初始化(和静态块被执行):

12.4.1 When Initialization Occurs A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

? T is a class and an instance of T is created.
? T is a class and a static method declared by T is invoked.
? A static field declared by T is assigned.
? A static field declared by T is used and the field is not a constant variable (§4.12.4).
? T is a top level class (§7.6), and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed.

12.4.1 初始化发生时 类或接口类型 T 将在以下任何一项第一次出现之前立即初始化:

? T 是一个类,并且创建了一个 T 的实例。
? T 是一个类,并且调用了一个由 T 声明的静态方法。
? 分配了由 T 声明的静态字段。
? 使用 T 声明的静态字段,该字段不是常量变量(第 4.12.4 节)。
? T 是顶级类(第 7.6 节),并且执行在词法上嵌套在 T(第 8.1.3 节)中的 assert 语句(第 14.10 节)。

回答by esaj

Static initializer-blocks aren't run until the class is initialized. See Java Language Specificationparagraphs 8.7 (Static initializers) and 12.4.1 (When initialization occurs):

静态初始化块在类初始化之前不会运行。请参阅Java 语言规范第 8.7 段(静态初始化程序)和 12.4.1(发生初始化时):

A static initializer declared in a class is executed when the class is initialized (§12.4.2). Together with any field initializers for class variables (§8.3.2), static initializers may be used to initialize the class variables of the class.

类中声明的静态初始值设定项在类初始化时执行(第 12.4.2 节)。与类变量的任何字段初始化器(第 8.3.2 节)一起,静态初始化器可用于初始化类的类变量。

Here's a similar example straight out of JLS 12.4.1:

这是直接来自 JLS 12.4.1 的类似示例:

class Super {
  static int taxi = 1729;
}
class Sub extends Super {
  static { System.out.print("Sub "); }
}
class Test {
  public static void main(String[] args) {
    System.out.println(Sub.taxi);
  }
}

This program prints only:

该程序仅打印:

1729

because the class Sub is never initialized; the reference to Sub.taxi is a reference to a field actually declared in class Super and does not trigger initialization of the class Sub.

因为 Sub 类从未被初始化;对 Sub.taxi 的引用是对 Super 类中实际声明的字段的引用,不会触发类 Sub 的初始化。

回答by BOSS

There is a single copy of myVarand both parent and child class will share the same. Untill and unless child class get initilized.

有一个副本,myVar父类和子类将共享相同的副本。直到和除非子类被初始化。

回答by Johnnie

Here is the link to the Java Specification - section 8.7 talks about static initializers. It gives good details about how they should function and the order in which they get called. http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.7

这是 Java 规范的链接 - 第 8.7 节讨论了静态初始化程序。它提供了有关它们应该如何运行以及它们被调用的顺序的详细信息。http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.7

回答by januprasad

When we do

当我们做

class Base {

    public static int myVar = 0;
    static {
        System.out.println("Base");
    }
}

class Derived extends Base {

    static {
        System.out.println("Derived");
        Base.myVar = 9;

    }
}

public class StaticBlock {

    public static void main(String[] args) {

        System.out.println(Base.myVar);
        System.out.println(Derived.myVar);
    }
}

The Output will be Base 0 0

输出将是 Base 0 0

That means derived class's static block not executing..!!

这意味着派生类的静态块没有执行..!!