如果我调用静态方法,构造函数 运行

If I call a static method, does the constructor run

我有一个名为 Tile 的 class,它有一个静态方法 public static BufferedImage grass(),在 class 内部还有一个构造函数 public Tile(),它设置了一个变量。

所以我想知道的是,如果我从另一个 class Tile.grass() 调用 grass() 方法,构造函数会 运行 吗?

我假设不是,因为我的 grass() 方法是 returning null

这是我的代码:

import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;

public class Tile {

    public static final int size = 50;

    private static BufferedImage mapSprites;

    public Tile(){
        try{
            Tile.setMapSprites(ImageIO.read(getClass().getResource("res/mas.png")));
        } catch (IOException e){
            e.printStackTrace();
        }
    }

    public static BufferedImage grass(){
        return getMapSprites().getSubimage(0, 0, 10, 10);;
    }

    private static BufferedImage getMapSprites() {
        return mapSprites;
    }

    private static void setMapSprites(BufferedImage mapSprites) {
        Tile.mapSprites = mapSprites;
    }
}

我可以创建一个函数,为我 return 的每个图块获取 mapSprite。但我认为这不会非常有效。还有其他解决方案吗?

(仅供参考,我在 Map class 中是这样称呼它的)

public void render(){
    g.drawImage(Tile.grass(), 0, 0, null);
}

没有。它不会。构造函数将在第一次(以及每次)创建 Tile 的 new 实例时执行。

如果您有一些代码想要 运行 一次,当 class(不是 instance) 初始化,你可以把它放在一个静态块中:

private static BufferedImage mapSprites;
static {
    try{
        Tile.setMapSprites(ImageIO.read(getClass().getResource("res/mas.png")));
    } catch (IOException e){
        e.printStackTrace();
    }
}

另一种方法是让您的 class 成为 Singleton

不,如果您只调用 class 的静态方法,构造函数不会 运行。没有 class 的实例与对静态方法的调用关联。这就是为什么 mapSpritesnull.

要填充 mapSprites,您可以将初始化它的代码移出构造函数并移入静态初始化程序。这样,它会在第一次引用 class 时 运行,因此当您第一次调用 static 方法时,mapSprites 会正确初始化。

static {
    try{
        Tile.setMapSprites(ImageIO.read(Tile.class.getResource("res/mas.png")));
    } catch (IOException e){
        e.printStackTrace();
    }
}

对于静态初始值设定项,您必须小心避免从中传播任何异常。如果是这样,那么它将被包裹在一个将被抛出的 ExceptionInInitializerError 中,这对你的程序来说是个坏消息。

您可能还想制作(现在无用的)构造函数 private,以防止实例化 class,因为您的 class 现在是一个实用程序 class ,其中所有内容均为 static,而此 class 的实例现在已无用。

您可以将图像初始化代码放在 static 初始化程序块中,因为它在所有 Tile 个实例之间共享。

static {
    try {
        Tile.setMapSprites(ImageIO.read(Tile.class.getResource("res/mas.png")));
    } catch (IOException e){
        e.printStackTrace();
    }
}

这样您就不必在每次创建新 Tile 实例时都加载图像。

关于您的原始问题,只有在您显式使用 new 运算符时才会调用构造函数,如 new Tile().