一、题目
编写一个程序,展示无论你创建了某个特定类的多少个对象,这个类中的某个特定的static域只有一个实例。
二、思路
2.1 域:猜想是个类中的字段的作用域。
2.2 首先定义个类,然后类中有多个字段,包含static声明的和非static声明的,然后创建两个对象,对比这两个对象的static字段结果。
三、解题
3.1 输入
E2_StaticScopeClass:创建测试static域基础类
//E2_StaticScopeClass:创建测试static修饰基础类
public class E2_StaticScopeClass {
Map input = new HashMap();
static Map staticInput = new HashMap();
}
E2_StaticScopeTest static域测试:分别测试静态字段和非静态字段结果
/**
* static域测试:分别测试静态字段和非静态字段结果
*/
public class E2_StaticScopeTest {
public static void main(String[] args) {
E2_StaticScopeClass scopeClass1 = new E2_StaticScopeClass();
E2_StaticScopeClass scopeClass2 = new E2_StaticScopeClass();
System.out.println("No Static scope test result:"+ (scopeClass1.input == scopeClass2.input));
System.out.println("Static scope test result:"+ (scopeClass2.staticInput == scopeClass2.staticInput));
}
}
3.2 输出
可以看出,创建不同实例时,非static域对象创建出的结果不同。而static域创建出的对象相同。进而可以得出结论:static域修饰对象只有一个,且当任意一个实例对象 (例如scopeClass1) 修改 staticInput时,所有使用该字段的地方都会进行修改。
No Static scope test result:false
Static scope test result:true
四、优化
官方答案使用了修改scopeClass1中的staticInput字段,进而判断scopeClass1.staticInput是否依然等于scopeClass2.staticInput。
仅供参考,可以添加到上述答案中。
4.1 输入
import java.util.HashMap;
import java.util.Map;
/**
* E2_StaticScopeTest static域测试:分别测试静态字段和非静态字段结果
*/
public class E2_StaticScopeTest {
public static void main(String[] args) {
E2_StaticScopeClass scopeClass1 = new E2_StaticScopeClass();
E2_StaticScopeClass scopeClass2 = new E2_StaticScopeClass();
System.out.println("No Static scope test result:"+ (scopeClass1.input == scopeClass2.input));
System.out.println("Static scope test result1:"+ (scopeClass2.staticInput == scopeClass2.staticInput));
System.out.println("StaticInput result1:"+ scopeClass2.staticInput);
Map result = new HashMap();
result.put("key", "value");
scopeClass2.staticInput = result;
System.out.println("Static scope test result2:"+ (scopeClass2.staticInput == scopeClass2.staticInput));
System.out.println("StaticInput result1:"+ scopeClass2.staticInput);
}
}
4.2 输出
No Static scope test result:false
Static scope test result1:true
StaticInput result1:{}
Static scope test result2:true
StaticInput result1:{key=value}
五、结论
Static域只有一个实例,且在对象初始化前就已经创建了唯一的存储空间。后续引用都会只会对其值做修改,但不会新建存储空间。而非static域会随着每次新建的对象实例新创建出存储空间。
Static作用于某个方法时,差别没有那么大,仅仅是避免需要创建实例就可以使用这个方法。
拓展:
1)为什么java要提供static字段能力呢?
解决:有两种情景,一是只想为某特定域分配一个单一的存储空间,后续便于单一使用唯一的这个变量。不用考虑创建多少对象,甚至不用创建对象。二是希望某个方法不与包含它的类的实例有任何关系,即使不用创建对象也能调用这个方法。(能力+高效+节省空间)。
2)Spring多线程使用该类static字段时,会是什么结果?
当一个线程修改类的该static字段,其他线程使用到static字段时会获取到修改后的值,而非static字段必须被new出一个对象才行,各个new出的对象字段相互独立,不会受影响。
3)Spring bean中存在static字段时,会怎样?
详见下篇文章:
结构设置:题目、思路、解题、纠错&优化、结论