[软件构造] 数据类型和类型检查

java数据

基本数据类型(Primitives)

对象数据类型(Object Reference Types)

没有引用,只有值

引用与对应的值不相同

不可变

有的可变,有的不可变

保存在栈中,被使用的时候才存在

保存在堆中,会被垃圾回收机制回收

使用成本低

成本高

基本数据类型(Primitives):

如int,long,double,boolean,char(首字母小写)

对象数据类型(Object Reference Types)(一般首字母大写)

  • Object类是所有类 的基类。所有类默认都继承了 Object类
  • 子类与其超类(父类)的关系:
    – 从其超类继承可见字段和方法
    – 可以覆盖(重写)方法来改变他们的行为
  • 一些分散的知识点:
    – 一些基本数据类型被封装为对象。如Boolean, Integer, Short, Long, Character, Float, Double。在使用构造collections容器的时候只能使用对象数据类型,但对容器操作的时候可以直接使用基本数据类型(语言会自动进行转换)。

1.如:List list = new ArrayList();
list.add(1);
2.上面list.add(1) 会自动执行list.add(Integer.valueOf(1)),但1不是对象类型,但编译能够通过,自动完成转换,但会降低效率;

– 重载运算符和方法:相同的操作名称用于不同 的数据类型。java不支持重载运算符(除了String的“+”运算(相当于执行 String c = (new StringBuilder(String.valueOf(a))).append(b).toString(); )等少量情况之外),或者说,java已经好了关于数字的运算符

变量类型的确定:

所有变量的类型在编译时(程序运行之前)都是已知的,因此编译器也可以推断出所有表达式的类型。如果a和b声明为int,则编译器断定a + b也是int。事实上,Eclipse环境在写代码的时候执行此操作,因此在编译之前打代码的时候IDE便会报错。但是在像Python这样的动态类型语言中,这种检查会延迟到运行时(程序运行时)。

类型检查:

  • 分类:
    – 静态检查:在程序运行之前自动发现错误。将操作应用于错误类型的参数会导致错误,静态检查会帮助避免因使用错误类型的操作而导致的错误。一般包括:语法错误、方法的参数个数种类、方法的返回类型等
    – 动态:执行代码时会自动发现错误。检查举例:
    1.非法参数值。 例如,当y实际为零时,在整数表达式x / y中是错误的
    2.超出范围的索引
    3.调用空对象的方法
    – 无:语言根本无法帮助您找到错误。 你必须自己观察,或者得到错误的答案
  • 类型转换,java会进行数据类型转换。基本数据类型的如
    double a = 2; // a = 2.0(隐式)
    int a = 18.7; // 报错
    int a = (int)18.7; // a = 18
    对象数据类型的,比如子类型可以转换为父类型,这里不细说了。
  • 静态、动态检查对比:
    – 静态检查针对类型,与变量 特定值无关的错误,某些变量的值 只有运行时才会知道,动态检查针对由特定值引起的错误。
    – 注:double的NaN不是动态检查出来的错误

可变与不可变类型

  • 改变变量和改变值的区别:对变量赋值是在改变变 量的指向,指向不同的值;改变可变变量的内容时 ,是在改变变量内部内容的引用。优秀的程序员避免改变变量,容易出问题。因此,我们有不可变类型
  • Immutability不变性
    – 概念:
    1.可变类型:一旦被创建,只代表固定值
    2.不可变:可以有改变对象值的方法
    – 不变性是一种主要的设计原则
    – java提供的final修饰符,保证不变引用,一旦指定引用位置,不可再次指定(final修饰的成员变量在构造方法里赋值),Final关键 字对不可变引用提供了静态检查的支持。注意
    1.final class意味着它不能被继承
    2.final variable(变量)意味着它始终包含相同的值/引用但不能更改;
    3.final method(方法)意味着它不能被子类覆盖;
    – 注意:引用不可变,但指向的值却可以是可变的数据类型属于可变类型

ArraysCollections

  • 数组(Arrays):长度固定的序列
  • List:可变长度的序列。具体实例化:如ArrayList 、LinkedList。注:1、List是一个接口,不可实例化。2、List的成员必须是对象类型
  • Set:零个或多个唯一对象的无序集合,对象不能重复出现。set是抽象接口。具体实例化:HashSet
  • Map:键值对,抽象接口。具体实例化:HashMap
  • 从Arrays建立list:
    Arrays.asList(new String[] { “a”, “b”, “c” })
  • collections:
    – b、c以及Quene的集合均继承自Collections,使用Collections的时候我们可以限制Collections中包含的对象类型。
    – 当添加一个成员时 ,编译器执行静态检查,确保只添加合适类型的成员。
  • 迭代器(Iterator):
    – 迭代器是一个对象,它遍历一组序列元素并逐个返回元素。遍历时默认调用迭代器。
    – 改变序列可能会破坏迭代器。比如迭代的时候不能从序列中remove元素

一些不可变类型

可变类型的不可变包装(Unmodifiable wrappers):List–Collections.unmodifiableList。Set – Collections.unmodifiableSet。Map – Collections.unmodifiableMap

空引用(Null references

  • 对象和数组的引用可以采用特殊值Null,这意味着引用不指向对象。注意:null是Java类型系统中一个不幸的漏洞
  • 基本数据类型,不能复制为null。可以为任何非基本数据类型赋值null,编译器在编译时很好地接受此代码。
  • 注意:null指的不是“”或者空的array或Collections,非空的collection可以包含null值
  • 由于粗心地使用null会导致各种各样的错误,null的含义含糊不清。比如Map.get(key)返 回null可能是key对应的值就是null,或者map中没有此key对应的值,所以建议不要使用null。而且,在参数和返回值中隐式禁止null。

总结

数据类型是编程的基础。java为我们提供了基本数据类型以及对象数据类型。合理的使用它们、了解它们的性质是进一步编程的基础。因此,一定要搞清基本数据类型与对象数据类型的区别,不要弄混了类、引用、对象等概念。

posted @ 2022-05-23 09:28  Matrix_250  阅读(28)  评论(0编辑  收藏  举报