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

时间:2015-05-18 16:42:02

标签: java constructor static scope static-methods

我有一个名为Tile的类,其中包含一个静态方法public static BufferedImage grass(),并且该类内部也是一个构造函数public Tile(),用于设置变量。

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

我假设没有,因为我的grass()方法正在返回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;
    }
}

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

(这里仅供参考,我在Map课程中调用它)

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

3 个答案:

答案 0 :(得分:12)

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

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

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

使用静态初始化程序时,必须小心避免任何异常传播。如果确实如此,那么它将被包裹在ExceptionInInitializerError中,这将是你的计划的坏消息。

您可能还想创建(现在无用的)构造函数private,以防止实例化类,因为您的类现在是一个实用程序类,其中所有内容都是static,并且实例为这堂课现在没用了。

答案 1 :(得分:1)

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

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

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

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

答案 2 :(得分:0)

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

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

这样,每次创建新的Tile实例时都不必加载图像。

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