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类不能被继承,引用不能被改变,但是引用地址指向的内存的地址存储的对象是可以改变的

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=c+"ds";
        System.out.println(b);
        System.out.println(c);
    }
}

运行内存图:


运行结果:

ddd
dddds

我们从此可以知道,上面的String c=b;并不是将b的地址复制给c,而是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也改变,因为他们指向得内存地址一样。

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

原文地址:https://www.cnblogs.com/zzuli/p/9381266.html

时间: 2024-10-22 00:12:51

final修饰的变量引用不能变还是对象不可变的相关文章

final修饰的变量是引用不能变还是对象的内容不能变?

int a=1;此时a是变量: StringBuffer a=new StringBuffer();此时a就是引用变量,可以说是a引用String对象,通过a来操作String 对象 final StringBuffer a=new StirngBuffer(); a=new StringBuffer();会报错: a.append("两");没错 这就说明final 修饰的变量是引用不能变,对象的内容可以变的:

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

我们都知道final修饰变量时 会变为常量,但是使 用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 下面让我们来看这段代码: /** * 验证final修饰的变量是引用不能变,还是引用的对象不能变 * StringBuilder 线程不安全 但速度快 * 引用初始化以后不能被改变 --- 不是指变量的值不可变,而是指向的变量地址不可变 * @author Tomato * */ public class TestFinal { public static void mai

浅谈final修饰的变量

一直大概的知道final关键字的作用,但是自己实际工作中却很少用,除非在声明一些常量值的时候,今天忽然自己在项目中用一个map进行存储一些值.一开始我只是用private修饰的,心里想的是如果final修饰的话,应该不能修改了.毕竟被final修饰的变量不可变.今天回家后,做了下面的尝试,彻底暴露出自己基础的不扎实. final的作用 被final修饰的类不可以被继承 被final修饰的方法不可以被重写 被final修饰的变量不可变 实战演示 1.首先看下面代码 public class Fin

并不是static final 修饰的变量都是编译期常量

见代码 public class Test { public static void main(String[] args){ // 情况一 基本数据类型 //System.out.println(Outer.Inner.n); // 输出结果 : 10 //情况二 //Outer outer = Outer.Inner.outer; // 输出结果 : 静态内部类 //情况三 System.out.println(Outer.Inner.str); // 输出结果: 静态内部类 abc //情

表达式转型注意事项,和final修饰的变量会被JVM优化

1java中表达式转型需要注意 实例如下: byte b1=1,b2=2,b3,b6; final byte b4=4,b5=6; b6=b4+b5; b3=(b1+b2); System.out.println(b3+b6); 问会出现什么状况:A.输出结果:13,B.b6=b4+b5 编译出错   C.b3=b1+b2编译出错   D.运行异常 首先表达式转型注意以下规则: ①所有的byte,short,char型的值将被提升为int型: ②如果有一个操作数是long型,计算结果是long型

final修饰的变量是引用不能改变,还是引用的对象不能改变???

对于这个问题,我们不能只记结论,要拿实例说话,参看以下代码: public class Demo { public static void main(String[] args) { final StringBuilder sb = new StringBuilder("haha"); //同一对象的hashCode值相同 System.out.println("sb中的内容是:" + sb); System.out.println(sb + "的哈希编码

java中使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?

是引用对象的地址值不能变,引用变量所指向的对象的内容是可以改变. final变量永远指向这个对象,是一个常量指针,而不是指向常量的指针. 例如:final StringBuffer sbu = new StringBuffer(“abc”); 在对其进行重新赋值 sbu = new StringBuffer(“”); 会出现编译错误,被final修饰的变量是不能被重新赋值的. sbu.append(“d”); 是可以编译通过的; final:最终.作为一个修饰符 1.可以修饰类.变量.函数. 2

《final修饰基本类型变量和引用类型变量的区别》

1 //final修饰基本类型变量和引用类型变量的区别 2 import java.util.Arrays; 3 class Person 4 { 5 private int age; 6 public Person(){} 7 public Person(int age) 8 { 9 this.age = age; 10 } 11 public void setAge(int age){this.age = age;} 12 public int getAge(){return age;} 1

java final 修饰变量

如果使用final修饰一个变量时,是值其引用的对象不变,而不是引用对象指向的内容.也是固定了栈内存的引用不变,不是修饰堆内存的内容. 如: