首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java基础知识中的澄清?

Java基础知识中的澄清?
EN

Stack Overflow用户
提问于 2009-12-12 20:31:46
回答 4查看 2.1K关注 0票数 11
代码语言:javascript
复制
class test {

    test() {
        System.out.println("Constructor");
    }

    {
        System.out.println("Hai");
    }

}

public class sample {

    public static void main(String [] a) {
        test t = new test();        
    }

}

在上面的代码中,为什么大括号((即) "Hai")中给出的语句是在构造函数执行之前打印的。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-12-12 20:50:56

让我们用一个更清楚的例子来表达:

代码语言:javascript
复制
public class Test {

    static {
         System.out.println("static initializer");
    }

    {
         System.out.println("instance initializer");
    }

    public Test() {
         System.out.println("constructor");
    }

}

并按如下方式进行测试:

代码语言:javascript
复制
public class Main {

    public static void main(String[] args) {
        Test test1 = new Test();
        Test test2 = new Test();
    }

}

输出:

代码语言:javascript
复制
static initializer
instance initializer
constructor
instance initializer
constructor

在运行时,特别是在类的加载期间,静态初始化器只执行一次。在构造函数之前的每次实例化过程中都会执行实例初始化器。

您可以拥有多个它们,并且它们将按照它们在编码中出现的顺序执行。

实例初始化器的主要优点是,无论您使用哪个构造函数,都会执行它们。它们适用于每一种方法,因此您不需要在所有方法上重复相同的初始化。

静态初始化器的主要优点是它们在类加载期间只执行一次。现实世界中一个众所周知的例子是JDBC驱动程序。当你这样做的时候

代码语言:javascript
复制
 Class.forName("com.example.jdbc.Driver");

它只执行static初始化器,那么任何(像样的) JDBC驱动程序都会在DriverManager中注册自己,如下所示:

代码语言:javascript
复制
 static {
      DriverManager.registerDriver(new com.example.jdbc.Driver());
 }

这样,DriverManager就可以在getConnection()期间找到正确的JDBC驱动程序。

票数 35
EN

Stack Overflow用户

发布于 2009-12-12 20:33:39

是。这是个instance initializer。一旦类被实例化,它就会立即运行。

票数 6
EN

Stack Overflow用户

发布于 2009-12-13 07:44:33

在上面的代码中,为什么大括号((即) "Hai")中给出的语句是在构造函数执行之前打印的。

因为这是Java Language Specification12.5 Creation of New Class Instances小节中描述的预期行为:)

在将对新创建的对象的引用作为结果返回之前,将使用以下过程处理指定的构造函数以初始化新对象:

  1. 将构造函数的参数分配给新创建的用于此构造函数调用的参数变量。
  2. 如果此构造函数以显式调用同一类中的另一个构造函数(使用this)开始,则使用这五个相同的步骤计算参数并递归处理该构造函数调用。如果构造函数调用突然完成,则由于同样的原因,此过程也会突然完成;否则,请继续执行步骤5。
  3. 此构造函数不会以显式调用同一类中的另一个构造函数(使用this)开始。如果此构造函数用于Object以外的类,则此构造函数将从显式或隐式调用超类构造函数(使用super)开始。使用同样的五个步骤,递归地计算参数并处理超类构造函数调用。如果构造函数调用突然完成,则此过程也会出于同样的原因突然完成。否则,继续执行类的实例初始化器和实例变量初始化器的步骤4.
  4. Execute,将实例变量初始化器的值赋给相应的实例变量,按照它们在类的源代码中以文本形式出现的从左到右的顺序。如果执行这些初始化器中的任何一个都会导致异常,则不会处理更多的初始化器,并且此过程会突然结束,但会出现相同的异常。否则,请继续执行步骤5。(在某些早期实现中,如果字段初始化器表达式是一个常量表达式,并且该常量表达式的值等于此构造函数主体的其余部分的type.)
  5. Execute的默认初始值,则编译器错误地省略了初始化字段的代码。如果该执行突然完成,则此过程也会因同样的原因突然完成。否则,此过程将正常完成。

有关...的更多详细信息,请参阅8.6 Instance Initializers部分。实例初始化器。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1893274

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档