String 及 final关键字

 

1.String对象

String对象是java中重要的数据类型,String对象的特点:不变性,常量池优化和String类的final定义。

1.1 不变性

String对象的状态在其被创建之后就不在发生变化。为什么说这点也是Java设计者所做的优化,在java模式中,有一种模式叫不变模式,了解的童鞋也应该知道不变模式的作用:在一个对象被多线程共享,而且被频繁的访问时,可以省略同步和锁的时间,从而提高性能。而String的不变性,可泛化为不变模式。

1.2 常量池优化

常量池优化指的是什么呢?那就是当两个String对象拥有同一个值的时候,他们都只是引用了常量池中的同一个拷贝。所以当程序中某个字符串频繁出现时,这个优化技术就可以节省大幅度的内存空间了。例如:

String s1  = "123";

String s2  = "123";

String s3 = new String("123");

System.out.println(s1==s2); //true  相同的地址

System.out.println(s1==s3);  //false 

                  s3虽然只与s1,s2相等,但是s3时通过new String(“123”)创建的,重新开辟了内存空间,因引用的地址不同.

System.out.println(s1==s3.intern());  //true  intern方法返回的是String对象在常亮池中的引用,所以最后一行打印出true。

1.3 final的定义

String类以final进行了修饰,在系统中就不可能有String的子类,这一点也是出于对系统安全性的考虑。

被final关键字修饰的类不能被继承,方法不能被重写,变量不能被修改

方法changeValue和main方法中的变量i根本就不是一个变量,因为java参数传递采用的是值传递,对于基本类型的变量,相当于直接将变量进行了拷贝。所以即使没有final修饰的情况下,在方法内部改变了变量i的值也不会影响方法外的i。 

class TestFinal {

    public static void main(String[] args) {
        TestFinal testFinal = new TestFinal();
        int i = 0;
        testFinal.changeValue(i);
        System.out.println(i); // 0

    }

    public void changeValue(final int i) {
        //final参数不可改变
        //i++;  编译时报错
        System.out.println(i); // 0
    }
}

final修饰引用类型的参数,不能再让其指向其他对象,但是对其所指向的内容是可以更改的。 

class TestFinal {

    public static void main(String[] args) {
        TestFinal testFinal = new TestFinal();
        StringBuffer buffer = new StringBuffer("hello");
        testFinal.changeValue(buffer);
        System.out.println(buffer);  // helloworld

    }

    public void changeValue(final StringBuffer buffer) {
        //final修饰引用类型的参数,不能再让其指向其他对象,但是对其所指向的内容是可以更改的。
        //buffer = new StringBuffer("hi");  编译报错
        buffer.append("world");
    }
}

 很显然,用final进行修饰虽不能再让buffer指向其他对象,但对于buffer指向的对象的内容是可以改变的。现在假设一种情况,如果把final去掉,结果又会怎样?


class TestFinal {

    public static void main(String[] args) {
        TestFinal testFinal = new TestFinal();
        StringBuffer buffer = new StringBuffer("hello");
        testFinal.changeValue(buffer);
        System.out.println(buffer); //hello

    }

    public void changeValue(StringBuffer buffer) {
        //buffer重新指向另一个对象
        buffer = new StringBuffer("hi");
        buffer.append("world");
        System.out.println(buffer); //hiworld
    }
}

原因在于java采用的是值传递,对于引用变量,传递的是引用的值,也就是说让实参和形参同时指向了同一个对象,因此让形参重新指向另一个对象对实参并没有任何影响

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值