• final修饰的变量引用不能变还是对象不可变


    两种情况:如果是基本数据类型,被final修饰的变量一旦初始化就不能改变;如果是引用数据类型的变量,初始化之后不能指向另外一个对象。

    基本数据类型:

    package cn.yqg.day2;
    
    public class StringTest {
         public static void main(String[] args) {
            final int a;
            int b=234;
            a=b;
            System.out.println(a);
        }
    }

    我们看到上面的代码a是final类型的,但是没有被初始化,所以可以给a赋值。如果a被初始化,a存储的值就不能改变了,示例如下。

    package cn.yqg.day2;
    
    public class StringTest {
         public static void main(String[] args) {
            final int a=123;
            int b=234;
            a=b;//编译通不过,会报错建议去掉fianl
            
            System.out.println(a);
        }
    }

    如果是引用数据类型

    -----------------------------------------------------------------------------------------------------------------------------------------------------------------

    package cn.yqg.day2;
    
    public class StringTest {
         public static void main(String[] args) {
            final StringBuffer a=new StringBuffer("ppp");
            System.out.println(a);
            System.out.println(a.hashCode());
            a.append("kkk");
            System.out.println(a);
            System.out.println(a.hashCode());
            
        }
    }

    运行结果:

    ppp
    2018699554
    pppkkk
    2018699554

    我们发现变量内容变了,引用没变。

    我们把String定义为final类型,那么String类不能被继承,开始创建对象ppp,并用指向ppp的存储地址,后来a=a+“kkk”会新创建一个内存来存储该对象,并把新的地址赋值给a,那么老的存储ppp对象的地址就没有变量赋值了,就会成为垃圾。

    String a="ppp";
     a=a+"kkk";

    我们看到a的对象内容改变了

    不允许String类的引用地址被改变是为了安全性着想,我们看这个例子。

    package cn.yqg.day3;
    
    public class Test2 {
        public static void main(String[] args) {
            String a=new String("fds");
            String b=new String("ddd");
            String c=b;//c和b都指向ddd对象
            c=c+"ds";//c会创建新的内存,内存中存储新的对象,这是ddd只有b指着,c指向新对象。
            System.out.println(b);
            System.out.println(c);
        }
    }

    运行内存图:


    运行结果:

    ddd
    dddds

    我们从此可以知道,c新开辟一个地址并进行存贮,这就保证了String类的安全性,相反StringBuilder就存在安全隐患

    package cn.yqg.day3;
    
    public class Test2 {
        public static void main(String[] args) {
            StringBuilder s=new StringBuilder("ppp");
            StringBuilder r=s;
            r.append("kkk");
            System.out.println(r);
            System.out.println(s);
        }
    }

    运行结果:

    pppkkk
    pppkkk

    r改变会导致s也改变,因为他们指向得内存地址一样。

    ------------------------------------------------------------------------------------------------------------------------------------------------------

  • 相关阅读:
    弹性盒子模型属性之flex-shrink
    Git----基本操作
    Git----简介
    ES6常用语法
    nginx学习
    Shell基础命令(二)
    Linux目录
    Shell基础命令(一)
    CRM之分页
    Django之ModelForm组件
  • 原文地址:https://www.cnblogs.com/zzuli/p/9381266.html
Copyright © 2020-2023  润新知