调用没有名称的Java方法。

时间:2022-01-28 19:09:21

I'm looking at the code below and found something a bit strange:

我在看下面的代码,发现了一些奇怪的东西:

public class Sequence {
    Sequence() {
        System.out.print("c ");
    }

    {
        System.out.print("y ");
    }

    public static void main(String[] args) {
        new Sequence().go();
    }

    void go() {
        System.out.print("g ");
    }

    static {
        System.out.print("x ");
    }
}

I would've expected this to give a compilation error as the System.out with "y " doesn't belong to a method declaration just a { }. Why is this valid? I don't see how this code would or should be called.

我希望这能给出一个编译错误作为系统。out with“y”不属于一个方法声明,只是一个{}。为什么这个有效吗?我不明白这段代码应该如何调用。

When running this it produces x y c g also, why does the static { } get called before the sequence constructor?

当运行它时,它也会产生x y c g,为什么静态{}在序列构造函数之前被调用?

8 个解决方案

#1


145  

This:

这样的:

static {
        System.out.print("x ");
    }

is a static initialization block, and is called when the class is loaded. You can have as many of them in your class as you want, and they will be executed in order of their appearance (from top to bottom).

是一个静态初始化块,在加载类时调用。您可以在您的类中拥有任意数量的它们,并且它们将按照它们的外观(从上到下)执行。

This:

这样的:

    {
        System.out.print("y ");
    }

is an initialization block, and the code is copied into the beginning of each constructor of the class. So if you have many constructors of your class, and they all need to do something common at their beginning, you only need to write the code once and put it in an initialization block like this.

是一个初始化块,并将代码复制到类的每个构造函数的开头。因此,如果您有许多类的构造函数,并且它们在开始时都需要做一些常见的事情,那么您只需要编写一次代码,并将其放入这样的初始化块中。

Hence your output makes perfect sense.

因此,您的输出非常有意义。

As Stanley commented below, see the section in the Oracle tutorial describing initializaiton blocks for more information.

正如Stanley所评论的,请参阅Oracle教程中描述initializaiton块的部分以获取更多信息。

#2


25  

Its not a method but a initialization block.

它不是一个方法,而是一个初始化块。

 {
    System.out.print("y ");
 }

It will be executed before the constructor call. While

它将在构造函数调用之前执行。而

static {
        System.out.print("x ");
       }

is static initialization block which is executed when class is loaded by class loader.

是在类装入器装入类时执行的静态初始化块。

So when you run your code
1. Class is loaded by class loader so static initialization block is executed
Output: x is printed
2. Object is created so initialization block is executed and then constuctor is called
Output: y is printed followed by c
3. Main method is invoked which in turn invokes go method
Output: g is printed

所以当你运行你的代码1。类装入类装入器,因此静态初始化块被执行输出:x打印2。对象被创建,因此初始化块被执行,然后constuctor被称为输出:y被打印,后面是c3。主方法被调用,然后调用go方法输出:g被打印出来。

Final output: x y c g
This might help http://blog.sanaulla.info/2008/06/30/initialization-blocks-in-java/

最终输出:x y c g这可能有助于http://blog.sanaulla.info/2008/06/30/initializs-blocks-injava/。

#3


16  

That's an instance initialization block followed by a static initialization block.

这是一个实例初始化块,然后是一个静态初始化块。

{
    System.out.print("y ");
}

gets called when you create an instance of the class.

在创建类的实例时调用。

static {
    System.out.print("x ");
}

gets called when the class is loaded by the class loader. So when you do

在类装入器装入类时调用。所以当你做

new Sequence().go();

the class gets loaded, so it executes static {}, then it executes the instance initialization block {}, afterwards the body of the constructor is called, and then the method on the newly created instance. Ergo the output x y c g.

类被加载,所以它执行静态{},然后它执行实例初始化块{},然后调用构造函数的主体,然后调用新创建的实例的方法。输出x y cg。

#4


15  

static {
        System.out.print("x ");
    }

Is a static block and is called during Class Loading

是静态块,在类装入时调用吗?

{
    System.out.print("y ");
}

Is an initialization block

是一个初始化块

You can have multiple initialization blocks in a class in which case they execute in the sequence in which they appear in the class.

您可以在类中有多个初始化块,在这种情况下,它们按照它们在类中出现的顺序执行。

Note that any initialization block present in the class is executed before the constructor.

注意,类中的任何初始化块都是在构造函数之前执行的。

#5


10  

static {
      System.out.print("x ");
}

is an initialization block shared by the class(as indicated by static), which is executed first.

是由类共享的初始化块(如静态所示),首先执行。

{
        System.out.print("y ");

}

is an initialization block shared by all objects(constructors) of the class, which comes next.

是类的所有对象(构造函数)共享的一个初始化块。

Sequence() {
        System.out.print("c ");
}

is a particular constructor for the class, which is executed third. The instance initialization block is invoked first every time the constructor is executed. That's why "y" comes just before "c".

是该类的一个特殊构造函数,它被执行为第三个。每次执行构造函数时,首先调用实例初始化块。这就是为什么“y”出现在“c”之前。

void go() {
        System.out.print("g ");
}

is just an instance method associated with objects constructed using the constructor above, which comes last.

只是一个与使用上面的构造函数构造的对象关联的实例方法,它是最后一个。

#6


9  

{
    System.out.print("y ");
}

These kinds of blocks are called initializer block. It is executed every time you create an instance of a class. At compile time, this code is moved into every constructor of your class.

这些类型的块称为初始化块。每次您创建类的实例时都执行它。在编译时,该代码被移动到类的每个构造函数中。

Where as in case of static initializer block: -

在静态初始化块的情况下:- ?

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

it is executed once when the class is loaded. We generally use static initializer block when the initialization of a static field, require multiple steps.

它在加载类时执行一次。我们通常使用静态初始化块,当初始化一个静态字段时,需要多个步骤。

#7


6  

It is used as an initialisation block and runs after any static declaration. It could be used to ensure that no one else can create an instance of the class (In the same way you would use a private constructor) as with the Singleton design pattern.

它被用作初始化块,并在任何静态声明之后运行。它可以用来确保没有其他人可以创建类的实例(就像使用私有构造函数一样),就像使用Singleton设计模式一样。

#8


3  

static {
    System.out.print("x ");
}

Static blocks are only executed once when the class is loaded and initialized by the JRE.

静态块只在类加载并由JRE初始化时执行一次。

And non-static block will be call every time your are creating a new instance and it will be call just before the Constructor.

当您创建一个新实例时,非静态块将会被调用,它将在构造函数之前调用。

As here you've created only 1 instance of Sequence so constructed has been called after non-static blocks and then the method which actually your goal.

在这里,您只创建了一个序列的实例,因此构建的序列是在非静态块之后调用的,然后是实际上您的目标的方法。

#1


145  

This:

这样的:

static {
        System.out.print("x ");
    }

is a static initialization block, and is called when the class is loaded. You can have as many of them in your class as you want, and they will be executed in order of their appearance (from top to bottom).

是一个静态初始化块,在加载类时调用。您可以在您的类中拥有任意数量的它们,并且它们将按照它们的外观(从上到下)执行。

This:

这样的:

    {
        System.out.print("y ");
    }

is an initialization block, and the code is copied into the beginning of each constructor of the class. So if you have many constructors of your class, and they all need to do something common at their beginning, you only need to write the code once and put it in an initialization block like this.

是一个初始化块,并将代码复制到类的每个构造函数的开头。因此,如果您有许多类的构造函数,并且它们在开始时都需要做一些常见的事情,那么您只需要编写一次代码,并将其放入这样的初始化块中。

Hence your output makes perfect sense.

因此,您的输出非常有意义。

As Stanley commented below, see the section in the Oracle tutorial describing initializaiton blocks for more information.

正如Stanley所评论的,请参阅Oracle教程中描述initializaiton块的部分以获取更多信息。

#2


25  

Its not a method but a initialization block.

它不是一个方法,而是一个初始化块。

 {
    System.out.print("y ");
 }

It will be executed before the constructor call. While

它将在构造函数调用之前执行。而

static {
        System.out.print("x ");
       }

is static initialization block which is executed when class is loaded by class loader.

是在类装入器装入类时执行的静态初始化块。

So when you run your code
1. Class is loaded by class loader so static initialization block is executed
Output: x is printed
2. Object is created so initialization block is executed and then constuctor is called
Output: y is printed followed by c
3. Main method is invoked which in turn invokes go method
Output: g is printed

所以当你运行你的代码1。类装入类装入器,因此静态初始化块被执行输出:x打印2。对象被创建,因此初始化块被执行,然后constuctor被称为输出:y被打印,后面是c3。主方法被调用,然后调用go方法输出:g被打印出来。

Final output: x y c g
This might help http://blog.sanaulla.info/2008/06/30/initialization-blocks-in-java/

最终输出:x y c g这可能有助于http://blog.sanaulla.info/2008/06/30/initializs-blocks-injava/。

#3


16  

That's an instance initialization block followed by a static initialization block.

这是一个实例初始化块,然后是一个静态初始化块。

{
    System.out.print("y ");
}

gets called when you create an instance of the class.

在创建类的实例时调用。

static {
    System.out.print("x ");
}

gets called when the class is loaded by the class loader. So when you do

在类装入器装入类时调用。所以当你做

new Sequence().go();

the class gets loaded, so it executes static {}, then it executes the instance initialization block {}, afterwards the body of the constructor is called, and then the method on the newly created instance. Ergo the output x y c g.

类被加载,所以它执行静态{},然后它执行实例初始化块{},然后调用构造函数的主体,然后调用新创建的实例的方法。输出x y cg。

#4


15  

static {
        System.out.print("x ");
    }

Is a static block and is called during Class Loading

是静态块,在类装入时调用吗?

{
    System.out.print("y ");
}

Is an initialization block

是一个初始化块

You can have multiple initialization blocks in a class in which case they execute in the sequence in which they appear in the class.

您可以在类中有多个初始化块,在这种情况下,它们按照它们在类中出现的顺序执行。

Note that any initialization block present in the class is executed before the constructor.

注意,类中的任何初始化块都是在构造函数之前执行的。

#5


10  

static {
      System.out.print("x ");
}

is an initialization block shared by the class(as indicated by static), which is executed first.

是由类共享的初始化块(如静态所示),首先执行。

{
        System.out.print("y ");

}

is an initialization block shared by all objects(constructors) of the class, which comes next.

是类的所有对象(构造函数)共享的一个初始化块。

Sequence() {
        System.out.print("c ");
}

is a particular constructor for the class, which is executed third. The instance initialization block is invoked first every time the constructor is executed. That's why "y" comes just before "c".

是该类的一个特殊构造函数,它被执行为第三个。每次执行构造函数时,首先调用实例初始化块。这就是为什么“y”出现在“c”之前。

void go() {
        System.out.print("g ");
}

is just an instance method associated with objects constructed using the constructor above, which comes last.

只是一个与使用上面的构造函数构造的对象关联的实例方法,它是最后一个。

#6


9  

{
    System.out.print("y ");
}

These kinds of blocks are called initializer block. It is executed every time you create an instance of a class. At compile time, this code is moved into every constructor of your class.

这些类型的块称为初始化块。每次您创建类的实例时都执行它。在编译时,该代码被移动到类的每个构造函数中。

Where as in case of static initializer block: -

在静态初始化块的情况下:- ?

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

it is executed once when the class is loaded. We generally use static initializer block when the initialization of a static field, require multiple steps.

它在加载类时执行一次。我们通常使用静态初始化块,当初始化一个静态字段时,需要多个步骤。

#7


6  

It is used as an initialisation block and runs after any static declaration. It could be used to ensure that no one else can create an instance of the class (In the same way you would use a private constructor) as with the Singleton design pattern.

它被用作初始化块,并在任何静态声明之后运行。它可以用来确保没有其他人可以创建类的实例(就像使用私有构造函数一样),就像使用Singleton设计模式一样。

#8


3  

static {
    System.out.print("x ");
}

Static blocks are only executed once when the class is loaded and initialized by the JRE.

静态块只在类加载并由JRE初始化时执行一次。

And non-static block will be call every time your are creating a new instance and it will be call just before the Constructor.

当您创建一个新实例时,非静态块将会被调用,它将在构造函数之前调用。

As here you've created only 1 instance of Sequence so constructed has been called after non-static blocks and then the method which actually your goal.

在这里,您只创建了一个序列的实例,因此构建的序列是在非静态块之后调用的,然后是实际上您的目标的方法。