就像标题所说,究竟有什么区别呢?
public static String myString = "Hello World!";
和
public static String myString;
static {
myString = "Hello World";
}
除了结构外,还有其他重要的区别吗?
就像标题所说,究竟有什么区别呢?
public static String myString = "Hello World!";
和
public static String myString;
static {
myString = "Hello World";
}
除了结构外,还有其他重要的区别吗?
就您的示例而言,没有任何区别。但正如您所看到的:
public static String myString = "Hello World!";
只能使用表达式初始化变量。然而,在静态初始化块(JLS 8.7)中,可以执行任意数量的语句。例如,可以这样做:
static
{
myString = "Hello";
myString += " ";
myString += "World";
}
就您的例子而言,显然没有必要这样做,但是有可能需要对变量进行初始化,所需的代码不止一个表达式,可能需要多个语句,因此Java引入了静态初始化器。
静态{...}块使您有机会完成比在字段声明中更多的工作。
例如,您可以填写地图的一些详细信息:
private static final Map<String, String> data = new HashMap<String, String>();
static {
data.put("A", "Hello");
data.put("B", "There");
data.put("C", "You");
}
public class Foo {
private static final Person person;
static {
InputStream personData = Foo.class.getResourceAsStream("something.txt");
person = new Person(personData);
}
...
}
静态初始化块和常规静态初始化的区别。
对于变量初始化,两者是相同的。
但是,如果我们想要连接数据库仅一次或加载任何操作仅一次。则在静态块中编写代码,因为它只会执行一次,当第一个类被加载时,无论您创建该类型的多少个对象。
编辑:
您还可以构建类似的块:
{
// Do Something...
}
例子:
public class Demo {
static{
System.out.println("Static");
}
{
System.out.println("Non-static block");
}
public static void main(String[] args) {
Demo demo = new Demo();
Demo demo2 = new Demo();
}
}
输出:
静态
非静态块
非静态块
在您的第一个示例中,变量在同一行声明并初始化。在第二个示例中,变量首先被声明,然后再进行初始化。在第二种情况下,您可能会在到达问题的初始化块之前进行任意数量的其他静态变量和块初始化。考虑以下情况:
public static String myString = "Hello World!";
public static String yourString = myString;
static {
System.out.println(myString);
System.out.println(yourString);
}
vs:
public static String myString ;
public static String yourString = myString;
static {
myString = "Hello World";
}
static {
System.out.println(myString);
System.out.println(yourString);
}
第一个示例的输出:
你好,世界 你好,世界
第二个示例的输出:
你好,世界 null
继Scott Stanchfield所说的,你可以使用Collections.unmodifiableXXX()
方法来确保安全性,尽管像Google Guava这样的库可能会使其不那么必要。请考虑以下内容:
public static final Map<String, String> CAPITALS;
static {
Map<String, String> map = new HashMap<>(); //Java 7.
map.put("NY", "Albany");
map.put("MD", "Annapolis");
map.put("VA", "Richmond");
map.put("CT", "Hartford");
// 46 more states
CAPITALS = Collections.unmodifiableMap(map);
}
public static final Map<String, String> CAPITALS = capitals();
private static Map<String, String> capitals() {
Map<String, String> map = new HashMap<>(); //Java 7.
map.put("NY", "Albany");
map.put("MD", "Annapolis");
map.put("VA", "Richmond");
map.put("CT", "Hartford");
// 46 more states
return Collections.unmodifiableMap(map);
}
使用静态块可以改变初始化的顺序,与声明的顺序不同。
静态变量存储一个在定义该变量的类的所有实例(或非实例)之间共享的值。
静态块是在类第一次加载时执行的代码段。
“就范围而言,静态块只能在同一类中访问”,而“静态变量可以从任何类访问”。
通常静态变量的值在该类的所有实例(或非实例)之间共享,而静态块是代码的一部分,在加载类时执行。在功能上没有区别。
非常惊讶的是,这里并没有明确回答最重要的特性。
是的,你可以有多行代码。但这有什么意义呢?你也可以在内联静态初始化赋值中只使用一次工厂方法调用。(static public final MyType mySPVar = factoryCreateObject();
)
所以让我们关注static public final
变量:
但如果那个方法(或你的任何多行代码)抛出Exception
甚至是Throwable
呢?
Checked Exceptions
(不是从RuntimeException
派生的)Unchecked Exceptions
RuntimeException
Throwable
,比如Error
if(myObj == null) {myObj = new Something();} return myObj;
(考虑同步!)