java对象和局部变量的使用:为什么方法属性上要加个final

我们查看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()'

猜你喜欢

转载自blog.csdn.net/habazhu1110/article/details/102744565
今日推荐