Java基本数据类型以及由不可变类带来的值传递和引用传递的难点分析 |
您所在的位置:网站首页 › 如何理解字符串变量是不可变量或不可变 › Java基本数据类型以及由不可变类带来的值传递和引用传递的难点分析 |
一、Java提供的数据类型
Java提供了8中原始的数据类型(byte,short,int,long,float,double,char,boolean),这些数据类型不是对象,相应的变量被定义后会立刻在栈上被分配内存空间。除此之外的数据类型,都是引用类型,引用类型在变量被声明时不会被分配内存空间,只是存储了一个内存地址而已。其实严格意义上讲,Java在8中数据类型外还提供了一种基本数据类型void,也有对应的封装类java.lang.void,只是无法直接对它进行操作。 注意:整数型的默认是 int 类型,带小数的默认是 double 类型。 各种数据类型字节长度对比表1字节 2字节 4字节 8字节 byte short int long boolean char float double 引申:Java中的null是什么? null不是一个合法的Object实例,它仅仅表明该引用类型目前没有指向任何对象,所以编辑器没有分配内存。与C语言一样,null是将引用变量的值置为0。 二、有关不可变类的理解不可变类(immutable class)是指当创建了这个类的实例后,就不允许修改它的值了,也就是说一个对象被创建以后,在整个生命周期内,它的成员变量就不能被修改了。有点类似与常量(const)不允许别的程序进行修改。 Java类库中,所有基本类型的包装类都是不可变类(Byte、Boolean、Short、Char、Integer、Float、Long、Double),此外String也是不可变类。 那么疑问来了,如下代码如何解释:String s = "Hello"; s += " World"; System.out.println(s); 运行结果是:Hello World 其实程序是在执行 s += " World" 时创建了一个新的对象"Hello World",s指向了这个新建的对象。原来的"Hello"字符串常量在内存中并没有被改变。 如此一来,下面的程序也就容易解释了。 public class Test{ public static void changeStringBuffer(StringBuffer ssb1,StringBuffer ssb2){ ssb1.append("world"); ssb2 = ssb1; } public static void main(String[] args) { Integer a = 1; Integer b = a; b++; System.out.println(a); System.out.println(b); StringBuffer sb1 = new StringBuffer("Hello sb1"); StringBuffer sb2 = new StringBuffer("hello sb2"); changeStringBuffer(sb1, sb2); System.out.println(sb1); System.out.println(sb2); } } 运行结果:
结果分析: 上面程序执行完 b++后,由于Integer是不可变类,因此会创建一个新值为2的Integer赋值给b,此时b和a已经没有任何关系。 对比理解StringBuffer类型的sb1、sb2以及引用传递入口的ssb1、ssb2,四者之间的引用关系变化。(StringBuffer是可变类) 调用函数前sb1和ssb1同时指向"Hello sb1",sb2和ssb2同时指向"Hello sb2"。调用完成后,ssb1改动了二者共同引用的地址空间的值,变为"Hello sb1word",同时ssb2指向了ssb1的引用地址空间,而外部的sb2的引用未受影响,以及sb2引用地址的值没有变化,故执行结果如结果所示。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |