Java静态Class变量初始化效率

Java Static Class Variable Initialisation Efficiency

我有以下内容:

public class ExampleObject extends GridObject { 
  private static Context c; 
  private static final String name = "Example Object"; 
  private static Bitmap skin = BitmapFactory.decodeResource(c.getResources(), R.drawable.defaultObject );
  private static float x,y; 

  public ExampleObject(Context c, float x, float y) { 
    this.c = c; 
    this.x = x; 
    this.y = y; 
  }
}

class 有 3 个静态 class 成员,图像是解码的位图,我希望它被解码一次,并且只用于该对象的所有实例。

在目前的状态下,这是实现了吗?还是每次创建此 class 的实例时都对其进行解码?

应该怎么做?

一个静态字段只会被初始化一次;这是由 JLS 保证的。

但是decodeResource方法会在class初始化的时候被调用,此时你的Context为null,所以会失败。如果你想要一个只初始化一次的静态字段,你需要更复杂的东西;更接近单例的东西。

public class ExampleObject extends GridObject { 
  private static final String name = "Example Object"; 
  private static Bitmap skin;
  // = BitmapFactory.decodeResource(c.getResources(), R.drawable.defaultObject );
  private static float x,y; 

  public ExampleObject(Context c, float x, float y) { 
    synchronized(ExampleObject.class) {
      if(skin == null) {
        skin = BitmapFactory.decodeResource(c.getResources(), R.drawable.defaultObject);
      }
    }
    this.x = x; 
    this.y = y; 
  }
}

您可以通过以下 class 定义实现预期的行为。

public class ExampleObject extends GridObject {
    private static Bitmap skin;

    public static Bitmap getSkin(Context c){
        if(skin == null){
            skin = BitmapFactory.decodeResource( c.getResources(), R.drawable.defaultObject );
        }
        return skin;
    }
}

静态变量仅初始化一次,并且它的一个副本将由 class 的所有实例共享。

这个单一的初始化过程是 运行 自动的,只有一次,当 class 第一次加载时。

您可能想使用 "static block" 来初始化 classes 的静态字段。 例如:

// start of static block 
    static {
        //initialize your static fields
        System.out.println("static block called ");
    }
    // end of static block