数据类型与类型检查
Posted szjk
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据类型与类型检查相关的知识,希望对你有一定的参考价值。
1.编程语言中的数据类型
数据类型和变量之间的区别:数据类型是抽象,而变量是对数据类型的具体实例化
int,long…类(classes),接口(interfaces),数组(arrays),枚举(enums),注解(annotations)
不可变的有些可变有些不可变
On stack,exist only when in use(栈中分配内存)On heap,garbage collected(堆中分配内存)
代价低代价昂贵
类的根是Object,所有类(除Object)均有父类。
当extends省略时默认继承自Object
包装类型
将基本类型包装为对象类型:Boolean, Integer, Short, Long, Character, Float, Double
通常是在定义集合类型的时候使用它们 eg:Map<Integer,Double> map = new HashMap()
Language does autoboxing and auto-unboxing 一般可以自动转换
Overloading operations 重载:同样的操作名可用于不同的数据类型
二.静态和动态类型检查
Java是一种静态类型的语言,在编译过程进行类型的检查;Python等语言是动态语言,在运行时进行类型检查
类型转换中可能出现的问题:
int a = 2; // a = 2
double a = 2; // a = 2.0 (Implicit)
int a = (int) 18.7; // a = 18
double a = (double)2/3; // a = 0.6666…
int a = 18.7; // ERROR
String a = 1; // ERROR
double a = 2/3; // a = 0.0
静态类型语言:所有变量的类型在编译阶段被确定,编译器能够推测出表达式的类型。在编译阶段进行类型检查。bug会在程序运行前被找出。eg:Java
动态类型语言:在运行阶段进行类型检查。bug会在程序执行时找出。eg:Python
静态类型检查:可在编译阶段发现错误,避免了将错误带入到运行阶段,可提高程序正确性/健壮性。
可检测出的类型:语法错误,类名/函数名错误, like Math.sine(2),参数数目错误, like Math.sin(30, 20),参数类型错误, like Math.sin(“30”),返回值类型错误, like return “30”; from a function that’s declared to return an int。
动态类型检查:非法的参数值(除0错误),非法的返回值错误,越界,空指针。
可检测出的类型:非法的参数值:除0错误; 非法的返回值 ; 越界:数组越界,集合越界 ; 空指针。
静态检查:关于“类型”的检查,不考虑值。
动态检查:关于“值”的检查
基本数据类型有时不是真正的数字:
1. 整数除法:5/2 会返回一个被截断的整数2
2. 整数溢出:int big = 200000*200000; 会返回一个错误的数值,并会躲过动态和静态类型检查
3. 浮点数溢出:Not a Number
int sum = 0;
int n = 0;
int average = sum / n;
System.out.println(average);//报错:除0错误
double sum = 7;
double n = 0;
double average = sum / n;
System.out.println(average);//输出Infinity
double probability = 1 / 5;
System.out.println(probability);//输出0.0
int a = 5; // (1)
if (a > 10) // (2)
int b = 2; // (3)
else // (4)
int b = 4; // (5)
// (6)
b *= 3; //静态类型检查错误(b cannot be resolved to a variable)
三,可变性与不可变性
改变一个变量:将该变量指向另一个值的存储空间。
改变一个变量的值:将该变量当前指向的值的存储空间中写入一个新的值。
如果是引用类型,也可以是不变的:一旦确定其指向的对象,不能再被改变。
可用关键字final修饰,使类型不可变。如果编译器无法确定final变量不会改变,就提示错误,这也是静态类型检查的一部分。
final 类无法派生子类
final变量无法改变值/引用
final方法无法被子类重写
不变对象:一旦被创建,始终指向同一个值/引用
可变对象:拥有方法可以修改自己的值/引用
eg:
string是不可变类型:一旦被创建,值就不可变。若要在String后添加,必须创建新的String对象。
StringBuilder是可变类型:内部存在修改方法
当存在多个引用对像时会存在差异
由此,可以看出对于不可变类型的频繁修改会产生大量垃圾,可变类型可获得更佳性能,也适合在多个模块间共享数据。但是,不可变类型更“安全”,在其他质量指标上表现更好。
传递可变的值出现的问题:
计算集合中绝对值的和时将所有元素都改为其绝对值,直接求和时无法求出正确结果。
返回可变的值出现的问题:
Data数据类型是可变的,在PartyPlanning中通过set函数将全局变量中的信息进行了改变
解决方案:
通过防御式拷贝,给客户端返回一个全新的Date对象return new Date(groundhogAnswer.getTime());
但是,大部分时候该拷贝不会被客户端修改,可能造成大量的内存浪费,最好采用不可变类型,避免了客户端修改问题,也不会出现防御式拷贝产生的内存浪费。
安全的使用可变类型:局部变量,不会涉及共享;只有一个引用,如果有多个引用(别名),使用可变类型就非常不安全
四.Snapshot diagrams快照图
基本类型:
对象类型:
不可变对象:用双线椭圆
不可变的引用:用双线箭头
引用是不可变的,但指向的值却可以是可变的
可变的引用,也可指向不可变的值
以上是关于数据类型与类型检查的主要内容,如果未能解决你的问题,请参考以下文章