Java:何时静态初始化块有用?
static
块中的初始化有什么区别:
public class staticTest { static String s; static int n; static double d; static { s = "I'm static"; n = 500; d = 4000.0001; } ...
和个人静态初始化:
public class staticTest { static String s = "I'm static"; static int n = 500; static double d = 4000.0001; ....
静态初始化块允许更复杂的初始化,例如使用条件:
static double a; static { if (SomeCondition) { a = 0; } else { a = 1; } }
或者,当不仅仅需要构build时:当使用构build器创build实例时,exception处理或除创build静态字段之外的工作是必需的。
内联静态初始化程序之后,也会运行一个静态初始化块,因此以下内容是有效的:
static double a; static double b = 1; static { a = b * 4; // Evaluates to 4 }
典型用法:
private final static Set<String> SET = new HashSet<String>(); static { SET.add("value1"); SET.add("value2"); SET.add("value3"); }
你怎么没有静态初始化?
初始化期间的exception处理是另一个原因 例如:
static URL url; static { try { url = new URL("https://blahblah.com"); } catch (MalformedURLException mue) { //log exception or handle otherwise } }
这对于令人讨厌地抛出检查exception的构造函数很有用,比如上面的,或者更复杂的初始化逻辑可能是exception容易的。
在你的例子中,没有区别。 但是通常初始值比在单个expression式中expression得舒服(比如,它是一个List<String>
其内容最好由for
-loop表示,或者它是一个可能不存在的Method
,所以exception处理程序是需要),和/或静态字段需要按照特定的顺序进行设置。
有时候你想做的不仅仅是把值赋给静态variables。 由于不能在类体中放置任意语句,因此可以使用静态初始化块。
static
块可以用来初始化单例实例,以防止使用同步的 getInstance()
方法。
从技术上讲,你可以逃脱。 有些更喜欢多行初始化代码进入静态方法。 我很高兴使用静态初始化器进行相对简单的多态初始化。
当然,我几乎总是把我的静力学做final
,指向一个不可修改的对象。
静态代码块能够使用多于指令的初始化字段,以不同的声明顺序初始化字段,也可以用于条件初始化。
进一步来说,
static final String ab = a+b; static final String a = "Hello,"; static final String b = ", world";
将不会工作,因为a和b是在ab之后声明的。
不过,我可以使用静态初始化。 阻止这个。
static final String ab; static final String a; static final String b; static { b = ", world"; a = "Hello"; ab = a + b; } static final String ab; static final String a; static final String b; static { b = (...) ? ", world" : ", universe"; a = "Hello"; ab = a + b; }
静态关键字(无论是variables还是块)属于该类。 所以当这个类被调用时,这些variables或者块就被执行了。 所以大部分的初始化都是在static关键字的帮助下完成的。 由于它属于类本身,类可以直接访问它,而不需要创build类的实例。
举一个例子,有一个鞋类,其中有颜色,尺寸,品牌等几个variables。在这里,如果制鞋公司只有一个品牌,我们应该把它初始化为一个静态variables。 所以,当鞋类被调用并且制造不同types的鞋(通过创build类的实例)时,当新的鞋被创build时,颜色和尺寸将占据记忆,但是在这里,品牌是所有鞋的共同属性,所以无论制造多less鞋,它都会占用一次内存。
例:
class Shoe { int size; String colour; static String brand = "Nike"; public Shoe(int size, String colour) { super(); this.size = size; this.colour = colour; } void displayShoe() { System.out.printf("%-2d %-8s %s %n",size,colour, brand); } public static void main(String args[]) { Shoe s1 = new Shoe(7, "Blue"); Shoe s2 = new Shoe(8, "White"); System.out.println("================="); s1.displayShoe(); s2.displayShoe(); System.out.println("================="); } }
如果你希望在首次使用类之前初始化指定的类静态types,那么静态初始化块是很有用的。 后续使用,将不会调用任何静态初始化块。 它与初始化实例成员的实例初始化器直接相反,