如果我调用静态方法,构造函数 运行
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 的实例与对静态方法的调用关联。这就是为什么 mapSprites
是 null
.
要填充 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()
.
我有一个名为 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 的实例与对静态方法的调用关联。这就是为什么 mapSprites
是 null
.
要填充 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()
.