数据类型与类型检验课程总结
数据类型
Java是一种强类型的编程语言,在编译和运行时都会进行严格的数据类型检验,因此,掌握各种数据类型的具体用法和内部存储机理,是必要的。
什么是数据类型
数据类型指定了变量可以存储的数据类型以及对应的操作。
Java有两种数据类型:基本数据类型和对象数据类型。基本数据类型包括int,long,boolean,double,char
等,对象数据类型包括String,BigInTeger
等Java自带的数据类型以及开发者自己定义的数据类型。
数据生活在哪里
我们已经知道了不同的数据类型,那么他们所对应的数据存放在哪里呢?
在这里我们引用老师ppt中的图表
可见,基本数据类型都存储在栈中,对象数据类型存储在堆中。
到这里,我们并没有完成对数据存储的解答,根据前文对数据类型的定义,数据类型指定了变量可以存储的数据类型
,因此,我现在想愚蠢地较个真,” 我已经知道数据存在哪了,那么表示数据的变量存储在哪里呢?”
对于基本数据类型,我们可以举个例子:
int age = 25;
当我们运行这个语句时,在栈内存中,会分配一个名为 age
的存储位置,并将整数值 25
存储在该位置。因此,变量只是一个名,它对应数据存储的地址,并不需要存储,注意:在这里,我只是较了个真,实际上,我们说变量,就是指它对应的那个数据,就像我们说张三,就是在说张三这个人,而不是“张三”这两个字
基本数据类型说完,那么对象数据类型呢?我们同样举个例子
String name = "张三";
我们刚才已经讨论了栈内存中,基本数据类型的存储,先前又说对象数据类型存储在堆中,那么我们是不是也可以说,当运行这个语句时,在堆内存中,会分配一个名为name
的存储位置,并将对象"张三"
存储在该位置?大错特错!!!实际上,并没有对象变量,只有对象引用变量 ,对象引用变量包含的二进制位表示了访问那个对象的一种方式,并不包含对象本身,而是包含一种类似“指针”或者地址的东西,而我们说,对象生活在堆中,因此,如果对象引用变量不在一个对象中,那么他就不在一个堆中,他在一个栈中!
那么刚才我“较的真”似乎有了点意义,允许我再重温一遍哈哈,“我们知道对象数据类型存储在哪里,那么表示对象的变量存储在哪里呢?”诶,按照我们刚才的推理,你知道答案了吧!如果它变量在一个对象中定义,那么它也存储在堆中,如果该变量在一个方法中定义,那么它就存储在栈中。挺有趣吧!
数据类型检验
编程语言可以按它们对数据的检验方式分为两类,静态类型语言和动态类型语言。静态类型语言有编译过程,并且在编译时会进行静态类型检查,在运行时会进行动态类型检查,比如Java,而动态类型语言没有编译过程,并且只在运行时进行动态类型检查,比如python。
静态类型检查可在编译阶段发现错误,避免了将错误带入到运行阶段,可提高程序运行正确性/健壮性。它可以检查语法错误,类名/函数名错误,参数数目错误,参数类型错误,返回值类型错误。
动态类型检查可以检查非法的参数值,非法的返回值,越界,空指针等错误。
不变性和可变性
我们日常开发过程中,很多错误都源于”变化“,变化的数值,变化的引用,变化的类型,可以说,变化是”罪恶“,但程序不能没有变化,那我们如何尽可能避免变化呢,就要考虑不变性和可变性
说了这么多,能不能给个例子让我感受一下?
String boyfriend = "张三";
我有个男朋友,他叫张三,我很爱他,但是有一天,一个坏蛋拿到了我的男朋友名单,然后
String boyfriend = "李四";
把我的男朋友变成了李四,oh!no!我试图找回张三,但是只有我一个人引用了他,只有我一个人记得他的名字,但是我现在引用了另一个人,因此,我只能看着他被垃圾回收器回收…
悲痛过后,我又遇到了一个我爱的人,现在我发誓绝对不会让他溜走,于是
final String boyfriend = "王五";
从此,我的男朋友只能是王五,谁也无法将我们分开了❤️❤️❤️…
注:这是引用的不变性,因为我系统地好好写太无聊了,所以玩点不太负责任的
嗯,我懂了,这是引用的不变性,然后呢,如果变化的是引用所对应的类型值,你怎么处理呢?
好的,我尝试仍然用上一个例子给你解答(:我爱整点自言自语)
现在时光回溯,让我们回到张三还在的日子,但是现在,我变成了那个坏蛋,刚才的我是我的情敌
现在,我拿到了我情敌的男朋友名单,但是,我不想让她的boyfriend指向别人,我恨我的情敌,我也恨张三!我要把张三变成狗!
于是,我赶紧翻阅跟String对象有关的方法,我发现了一个replace(" “,” ")方法可以替换字符串中的值,于是 😏 😏
boyfriend.replace("张三","狗");
运行之后我发现boyfriend怎么没有变化!怎么还是张三?这时我看到内存区出现了一条狗,他怒气冲冲地朝我跑来,大声斥责我说,”你个大坏蛋,竟做出如此下流的举动!可惜你并不知道,Java为了防止你这种小人背后破坏,早已经将String设置为不可变类型!所以你刚才的操作只会生成一个新的String类型在内存区,并不会改变原有变量的值。反正也没人引用我,我早晚会被垃圾回收器杀死,我要趁我死之前,与你这个坏蛋同归于尽…嗷呜“
注:这是类型/值的不变性,为了保护程序,Java设定所有基本数据类型都具有不变性,同时一些对象数据类型,比如String也具有不可变性