我们查看spring的时候经常能看到一些void方法采用对象传递的方式,例如.
public class Test {
public static void main(String[] args) {
Test t=new Test();
List<HashMap> list=new ArrayList<HashMap>();
t.test(list);
System.out.printf("==="+list.size());
}
private void test(List<HashMap> list){
list.add(new HashMap());
}
}
//打印的结果
===1
通过外调的方式改变了list对象的属性.
but
public class Test {
public static void main(String[] args) {
Test t=new Test();
List<HashMap> list=new ArrayList<HashMap>();
t.test(list);
System.out.printf("==="+list.size());
}
private void test(List<HashMap> list){
list=new ArrayList<HashMap>();
list.add(new HashMap());
}
}
这个结构就是===0
而且会发现一个
Parameter can be converted to a local variable
This inspection searches for redundant method parameters that can be replaced with local variables. If all local usages of a parameter are preceded by assignments to that parameter, the parameter can be removed and its usages replaced with local variables.
在list上的警告, 意思就是list参数是个局部变量,你不用传进来.说白了他是自己创建了一个list地址,用new ArrayList的地址,也就是说list不会改变, 所以这种方式我们要用final做限制是最稳妥的
public class Test {
public static void main(String[] args) {
Test t=new Test();
List<HashMap> list=new ArrayList<HashMap>();
t.test(list);
System.out.printf("==="+list.size());
}
private void test(final List<HashMap> list){
ArrayList l=new ArrayList<HashMap>();
l.add(new HashMap());
list.addAll(l);
}
}
//-----这样的结果就是==1
之前一直不明白为什么spring在入参属性上要加个final.如果说是int String我们可以理解为不让下游修改,对象通过get,set是可以修改的,这下豁然开朗了,局部变量的时候如果一旦出现地址变更,变更是不会传递的, 比如test(List list)这个list是局部变量自己创建了一个list,然后传参地址指向. 当里面出现new ArrayList()的时候其实是把list的指向地址指向了新的new ArrayList();地址, 此时list就和传进来的彻底失去了联系.所以
public class Test { public static void main(String[] args) { Test t=new Test(); List list=new ArrayList(); t.test(list); System.out.printf("==="+ JSONObject.toJSONString(list)); } private void test( List list){ list.add(1); list=new ArrayList(); list.add(2); list.add(3); } }
结果===[1] 因为在第一次加入指针还在主方法上, 后面两次已经到了新的new ArrayList()'