fianl static HashMap<> HASH_MAP = new HashMap<>();
这样使用hashmap会有什么影响呢?
第一反应是这个hashmap一旦存进去值,就不能变了。 结果是错的,存进去之后还可以变。
HASH_MAP.put(2,2+"id");
HASH_MAP.put(2,"id"+2);
结果是不报错的。
第二反应是这个hashmap第一次初始化之后,它的各项属性值不能变了,比如说Capacity、size等等。结果还是错的,这些属性还是可以变化。
static final HashMap<Integer,String> HASH_MAP = new HashMap<>(16);
public static void main(String[] args){
Class c1 = (Class)HASH_MAP.getClass();
Field[] fs = c1.getDeclaredFields();
for(int j =0;j<fs.length;j++){
Field field = fs[j];
field.setAccessible(true);
Object val = field.get(HASH_MAP);
System.out.println("name:"+field.getName()+"\t value = "+val);
}
System.out.println("------------------------");
for(int i = 0;i<10000;i++){
HASH_MAP.put(i,i+"id");
// System.out.println(i+1);
}
for(int j =0;j<fs.length;j++){
Field field = fs[j];
field.setAccessible(true);
Object val = field.get(HASH_MAP);
System.out.println("name:"+field.getName()+"\t value = "+val);
if (field.getName().equals("UNTREEIFY_THRESHOLD")){
field.set(HASH_MAP,7);
System.out.println("name:"+field.getName()+"\t value = "+val);
}
}
}
这里仅仅是对它的size进行增加,发现不管你put多少个对象进行都是可以的。并且它的size和modCount、threshold都发生了改变。所以说之前的猜想又不对。
下面的运行结果是去掉对UNTREEIFY_THRESHOLD赋值之后的运行结果。loadFactor、UNTREEIFY_THRESHOLD等属性是final修饰的,所以是不能变的;threshold、size等属性没有被final修饰,但是与hashmap内部机制有关,所以你改了也没用。
所以说只剩下一种可能会报错,就是对这个已经初始化好了的hashmap对象重新进行初始化操作。
static final HashMap<Integer,String> HASH_MAP = new HashMap<>();
HASH_MAP = new HashMap<>(16);
果然只有这样的操作才会报错。
总结
final static修饰其实在刚才的实验过程中起作用的只有final。当final修饰变量时,对于基本类型和string,这个变量的值是不能改变的;当修饰其他类型的对象时,final使其引用恒定不变,但是对象自身却可以自由修改变换。