麻省理工Java软件构造 Reading 1: Static Checking

原网页链接:
MIT Software Construction 课程网站 Reading 1: Static Checking

数据类型

类型(type)就是一组数据,以及对这些数据的操作

Java中的数据类型:

  • 基本类型(primitive types)
    如 int,long,boolean,double,char

  • 对象类型(object types)

    String (一组的char)
    BigInteger (可以表示任意大小的整数,不像int一样有范围的限制)

根据Java的惯例,基本数据类型都是小写字母组成的单词,而对象类型以一个大写字母开头

对数据的操作:
操作其实就是接受输入并产生输出的函数(有时还会改变输入数据本身的值)
Java中的操作有3中不同语法:

  • 中缀、前缀或后缀操作符

    如2个整数的“相加”操作 a + b,
    就是调用了+ : int × int → int这样的操作(在这种表示法中:+是操作的名称,箭头前的int×int描述了两个输入的类型,箭头后的int描述了输出类型)

  • 对象的方法(method)
    方法就是对某个对象的操作,
    例如,bigint1.add(bigint2),就是对前面bigint1这个对象进行操作,把它的值加上了后面的bigint2。
    调用了操作add: BigInteger×BigInteger→BigInteger

  • 函数
    例如,Math.sin(theta)
    调用操作sin: double→double。和对象的方法不同,Math不是一个对象,它是包含sin函数的类

操作的重载:相同的操作名作用在不同的类型上的情况就叫做重载。
例如对于Java中的基本数字类型,算术运算符+、-、*、/就被严重重载(它们可以被作用在int,long,double等类型上,数据类型是不同的,但是操作的名称是一样的,因此是重载)
方法也可以重载,大多数编程语言都有一定程度的重载

静态类型语言(statically-typed language)

Java是一种静态类型的语言。也就是说,所有变量的类型在编译时(程序运行之前)是已知的,因此编译器也可以推断出所有表达式的类型。如果a和b被声明为int型,那么编译器就会得出a+b也是int型的结论。实际上,Eclipse环境在你编写代码时就会这样做,所以当我们在写代码的时候就会发现许多错误(也就是warning和error),而不用等到运行才发生错误

静态类型是一种特殊的静态检查,这意味着在编译时检查bug。本课程中的许多想法都是为了消除代码中的bug,而静态检查是第一个方法。静态类型可以防止大量的bug感染您的程序:确切地说,是由于将操作应用到错误类型的参数而导致的bug。如果你写了如下的代码:

 "5" * "6"

也就是说你尝试将两个字符串相乘,那么静态类型检查将在你敲出这行代码后就捕获此错误,而不是等到你执行程序后程序运行到这行代码的时候才报错

静态检查,动态检查,以及,没有检查

  • 静态检查(Static checking):在程序运行之前就自动发现错误
  • 动态检查(Dynamic checking):在代码执行过程中自动发现错误
  • 没有检查:语言本身无法找到错误。你必须自己去检查(调试),否则就会得到错误的答案。

静态检查和动态检查的区别:
静态检查往往与类型错误有关,这些错误与变量的特定值无关。静态检查能保证一个变量会是某种类型而不会是其他类型(比如 int a,就保证了a在接下来的程序中会是int型)。
但是我们直到运行时才知道这些变量到底有哪些值。因此,如果错误只是由某些值引起的,比如“a/b”在运行时遇到b == 0的情况,或(数组等的)索引超出(数组的)范围,那么编译器就不会产生关于它的静态错误。
相比之下,动态检查往往与特定值引起的错误有关。

原始数据类型和实际数学上的数是有区别的

比如

  • 整数的除法
int a = 5;
int b = 2;
int c = a/b;
//c == 2 rather than 2.5

这个例子中,5/2并不会返回一个分数,而是一个向下取整了的整数

  • 整数的溢出
    int,long都是有具体范围的整数,int的范围是 [-231,231-1],long的范围是 [-263,263-1],如果一个int或long,经过运算后的结果过大或过小,超过了应有的范围,就会发生溢出,过大的数会变成一个负数,过小的数会变成一个正数

  • 浮点数的特殊值

像double一样的浮点数,就有NaN(不是一个数),POSITIVE_INFINITY(正无穷), NEGATIVE_INFINITY(负无穷)这三种特殊值

数组和集合

数组是一组特定长度的数据类型,我们可以这样定义一个数组

int[] a = new int[100];

因为有特定的长度,因此当数组的索引超过数组的范围时,就会有许多错误发生,这就是缓冲区溢出

因此不推荐使用固定长度的数组,而是使用列表(List)类型,这是一组包含许多数据类型T的可变长度的序列

List<Integer> list = new ArrayList<Integer>();

List 的一些操作:

  • 取出索引处存放的值: list.get(2)

  • 为索引处的元素赋值: list.set(2, 0)

  • 得到list的长度: list.size()

    注意,上面代码中List是一个接口,它是一种不能直接用new构造的类型,但是它指定了List必须提供的操作。我们将在以后的抽象数据类型的课程中讨论这个概念。ArrayList是一个类,一个提供这些操作实现的具体类型。ArrayList并不是列表类型的唯一实现,LinkedList是另一种。

你可以在Java API文档中查看它们,搜索“Java 10 API”即可。好好利用API,它们是你的好朋友(“API”指的是“应用程序编程接口”,这里指的是Java提供的帮助您构建Java应用程序的方法和类。)

需要注意的是,我们写的是List<Integer>,而不是List<int>。列表只知道如何处理对象类型,而不知道如何处理基础数据类型。在Java中,每个基础数据类型(通常用小写字母和缩写形式编写,如int)都有一个等价的对象类型(大写且全拼,如Integer)。Java要求我们在用尖括号参数化类型时使用这些等价的对象类型。
但是在其他情况下,Java会自动在intInteger之间进行转换,因此我们可以编写int i = 5而不会出现任何错误。

方法(method)

在Java中,程序语句通常必须在一个方法中,而且每个方法都必须在一个类(class)中,所以编写我们的hailstone程序(MIT的示例程序)的最简单方法是这样的:


public class Hailstone {
    /**
     * Compute a hailstone sequence.
     * @param n  Starting number for sequence.  Assumes n > 0.
     * @return hailstone sequence starting with n and ending with 1.
     */
    public static List<Integer> hailstoneSequence(int n) {
        List<Integer> list = new ArrayList<Integer>();
        while (n != 1) {
            list.add(n);
            if (n % 2 == 0) {
                n = n / 2;
            } else {
                n = 3 * n + 1;
            }
        }
        list.add(n);
        return list;
    }
}

public表示程序中任何地方的任何代码都可以引用类或方法。而其他访问修饰符(如private)使程序获得更多的安全性,并保证不可变类型的不变性(在以后的课程中讨论它)

static意味着该方法是一个不接受self参数的函数(在Java中,self是一个名为this的隐式参数,永远不会成为方法参数)。静态方法不会在对象上调用。这与List add()方法或String length()方法不同,这些方法它们要求首先有一个对象。相反,调用静态方法的正确方法是使用类名而不是对象引用:

//add()方法是非静态的,作用在“list”这个对象上
//因此调用add()的时候要先写出对象的名字
List<Integer> list = new ArrayList<Integer>();
list.add(2);

//hailstoneSequence()是静态方法
//调用的时候直接写出类的名字,然后再跟着方法名
Hailstone.hailstoneSequence(83)

就我个人理解,非静态的方法其实是作用在一个具体的对象身上的,因此,需要先有这个“对象”,才能对其进行这个“方法”的操作。而静态方法就不一样了,它不是对某个对象的操作,因此不需要先声明一个对象。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值