软构学习-4-数据类型与类型检验

Posted blogstb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了软构学习-4-数据类型与类型检验相关的知识,希望对你有一定的参考价值。

4 数据类型与类型检验

章节大纲:

  • 静态/动态类型检查
  • 可变/不可变数据类型
  • 可变数据类型的危险性
  • 不可变数据类型的优越性
  • 用 Snapshot 图理解数据类型
  • 用集合类表达复杂数据类型

Java中的数据类型

  • 基本数据类型
    如int、long、byte、short、char、float,double、boolean,都是不可变得数据类型
  • 对象数据类型
    如Classes、interfaces。arrays、enums、annotations,其中一些是可变的,一些是不可变的。

各种关系:

  • 继承(extends)
  • 重载

静态/动态数据类型检查

  • 静态数据类型检查
    发生在编译阶段
    包括:
  • 语法错误
  • 类名/函数名错误
  • 参数数目错误
  • 参数类型错误
  • 返回值类型错误
  • 动态数据类型检查
    发生在运行阶段
    包括:
  • 非法的参数值
  • 非法的返回值
  • 越界
  • 空指针

可变与不可变

改变一个变量和改变一个变量的值的区别:

  • 改变一个变量:
    将该变量指向另一个值的存储空间
  • 改变一个变量的值:
    将该变量当前指向的值的存储空间中写入一个新的值。

常见的不可变类型:

  • String

常见的可变数据类型:

  • StringBuilder

优劣:

  • 不可变数据类型:
    • (劣)在频繁修改时会产生大量不必要的拷贝以导致空间的浪费。
    • (优)更加安全
  • 可变数据类型
    • 与不可变数据类型相反

提高安全性的方法:

  • 防御式编程

Snapshot Diagram

基本数据类型和对象数据类型的表示区别:

可变/不可变数据类型的可变引用:

不可变的应用是双重箭头

Java学习笔记:数据类型与变量

数据类型

Java中存在2种数据类型,下面我们来详解一下:

  1. 基本数据类型;
  2. 引用数据类型;

可以用一张表来记录:

技术分享

基本数据类型

整型

  • byte:1个字节8位,取值范围为:[-128, 127],直接写值:(byte) 1;
  • short:2个字节16位,取值范围为:[-32768, 32768],直接写值:(short) 1;
  • int:4个字节32位,取值范围为:[-2147483648, 2147483648],直接写值:1;
  • long:8个字节64位,取值范围为:[-9233372036854477808, 9233372036854477808],直接写值:1L;
  • char:2个字节16位,取值范围为:[0, 65535],直接写值:(char) 1或‘a‘;

(注意Java中没有无符号类型,需要使用无符号类型需要自行扩展,可以参考我的扩展类库

浮点型

  • float:4个字节32位,直接写值:1.0F;
  • double:8个字节64位,直接写值:1.0D;

布尔型

  • boolean:1个字节8位,取值范围为:true或false;

引用数据类型

  • String:字符串类型,无长度限制,直接写值:"abc";
  • java.math.BigInteger:基本数据中的整型不能满足需求时可以使用该类来表示任意大小的整型数据;
  • java.math.BigDecimal:基本数据中的浮点型不能满足需求时可以使用该类来表示任意精度的浮点型数据;
  • 其他类型:类、接口、数组等其他类型;

栈和堆

栈内存

在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配。当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。

堆内存

堆内存用于存放由new创建的对象和数组。在堆中分配的内存,由java虚拟机自动垃圾回收器来管理。

从堆和栈的功能和作用来通俗的比较,堆主要用来存放对象的,栈主要是用来执行程序的。

另外,栈内存的内容会在作用域结束时自动移除,而堆内存的释放要借助Java的垃圾回收机制来完成。

包装类

不同于C#的万物皆对象,Java中,基本数据类型仅仅是数据而非对象,所以为了能将基本类型视为对象进行处理,并能连接相关的方法,java为每个基本类型都提供了包装类。以便将基本数据类型作为一个对象来处理。

C#中一切皆对象,所以将一个数字转换为16进制可以这么写:

254.ToString("x");//输出FE

但是在Java中,整型数据并不是对象,所以需要这么写:

new Integer(254).toString();//输出字符串"254"

包装类功能

  1. 提供数据的最大值与最小值;
  2. 提供转换为其他数据类型的功能;
int i = 5;//直接在栈中分配空间 
Integer i = new Integr(5);//对象是在堆内存中,而i(引用变量)是在栈内存中 

当需要往ArrayList,HashMap中放东西时,像int,double这种基本类型是放不进去的,因为容器都是装object的,这是就需要这些基本类型的包装类。

  • 原始类型 包装类
  • boolean Boolean
  • char Character
  • byte Byte
  • short Short
  • int Integer
  • long Long
  • float Float
  • double Double

变量

在Java中定义变量的写法如下:

int a = 0;
int b = 1, c = 2;

作用域

在栈内存中定义的变量是存在作用域的:

  1. 使用大括号来定义作用域;
  2. 作用域可以嵌套,子作用域可以访问父级的变量,父作用域不能访问子级的变量;
  3. 同一个作用域中的变量名不能重复;
  4. 离开作用域变量会被JVM自动回收;

下面我们看几个例子:

1 public static void main(String[] args)
2 {
3     int a = 0;
4     {
5         int b = 1;
6         a = 10;
7     }
8     a = b;//这行编译报错, 变量 b 离开自身作用域后就被回收了, 不能访问
9 }
 1 public static void main(String[] args)
 2 {
 3     int a = 0;
 4     {
 5         int b = 1;
 6         a = 10;
 7     }
 8     int b;//这个 b 是当前作用域创建的新变量, 值为默认的 0 而不是 1
 9     a = b;//不报错, b 可以访问到
10 }
1 public static void main(String[] args)
2 {
3     int a = 0;
4     {
5         int a = 100;//报错, 子作用域不能使用父级已经存在的变量名
6     }
7 }

类型转换

数据类型之间常常会需要相互转换,下面我们来看看;

小数据向大数据转换

由JVM自动完成,不需要进行额外处理,称为隐式类型转换,如:

 1 public class Main
 2 {
 3     public static void main(String[] args)
 4     {
 5         byte a = 16;
 6         short b = a;
 7         int c = b;
 8         long d = c;
 9 
10         float e = 16.66f;
11         double f = e;
12         
13         test(a);
14         test(e);
15     }
16 
17     private static void test(int i)
18     {
19     }
20 
21     private static void test(double i)
22     {
23     }
24 }

整数转换为浮点数时会出现精度丢失的情况。

大数据向小数据转换

需要强制转换,称为显式类型转换,如:

 1 public class Main
 2 {
 3     public static void main(String[] args)
 4     {
 5         long a = 1L;
 6         int b = (int) a;
 7         short c = (short) b;
 8         byte d = (byte) c;
 9 
10         double e = 16.66f;
11         float f = (float) e;
12 
13         test((byte) a);
14         test2((float) e);
15     }
16 
17     private static void test(byte i)
18     {
19     }
20 
21     private static void test2(float i)
22     {
23     }
24 }

转换时要注意数据越界的问题。

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

软构笔记-7-面向对象的编程

软构笔记-8-ADT和OOP中的“等价性”

软构学习-2-软件测试与测试优先的编程

软构笔记-9-面向复用的软件构造技术

Java:Effective java学习笔记之 列表优先于数组

磁盘检验