数据类型与类型检查

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快照图

基本类型:

技术图片

 对象类型:

 技术图片

 不可变对象:用双线椭圆

 技术图片

 不可变的引用:用双线箭头

 技术图片

引用是不可变的,但指向的值却可以是可变的
可变的引用,也可指向不可变的值

以上是关于数据类型与类型检查的主要内容,如果未能解决你的问题,请参考以下文章

redis 系列15 数据对象的(类型检查,内存回收,对象共享)和数据库切换

[redis读书笔记] 第一部分 数据结构与对象 对象特性

强/若类型语言 动/静态语言

如何在循环中读取数据框列值并检查每列的数据类型

MySQL数据类型--------枚举与集合类型实战

软件构造课程提纲