软件构造之Java 类型

什么是类型

类型是由一系列值的集合,以及可以在这些值上执行的操作组成

在Java中有几种基本的数据类型,他们是:
整型(如5和200,范围为在正负2的31次方之间,大致为正负20亿)。
长整型(较大的整数,最大为2的63次方) 
布尔类型(值为true或false)           
双精度浮点数(用于浮点数,表示实数的子集)          
字符(如“A”和“$”等单个字符)

java也有对象类型,例如:              
字符串表示一系列字符,如字符串“Java”   
BigInteger表示一个任意大小的整数
在java的公约中,原始类型是小写,而对象类型以大写字母开始。    

操作         

操作是根据输入值产生输出值的函数。(一个操作有时也会改变输入值,也就是所谓的突变)。操作的语法各不相同,但不管怎样编写,我们仍然把它们看作函数。这里是在python或java运行三种不同的语法:             

作为一个前缀,中缀或后缀运算符。例如,A + B调用操作+:int x int →  int
作为对象的方法。例如,bigint1.add(bigint2)调用操作添加:BigInteger×BigInteger→BigInteger。            
作为函数。例如,math.sin(θ)调用操作的正弦值:double→double。          

有些操作是重载的,即不同类型使用相同的操作名。如,在Java中,算术运算符+,-,*,/被大量重载。方法也可以重载。大多数编程语言都有一定程度的重载。 

 

静态类型语言

java是一种静态类型语言。所有变量的类型必须在编译时(在程序运行之前)被编译器知道,因此编译器也可以推断所有表达式的类型。如果A和B都声明为int,那么编译器认为A + B也是一个int的数据类型,而在像Python这样的动态类型语言中,这种检查被推迟到运行时(程序运行时)。

静态类型是静态检查的一种特殊类型,这意味着在编译器会在编译时检查错误。Bug是编程的祸根,静态类型防止了一大类bug影响程序的运行:确切地说,这些bug是将操作应用于错误类型的参数而导致的。如果你写了一行代码:   "5" * "6",它试图将两个字符串相乘。静态类型可以在程序员仍在编程时捕捉到这个错误,而不是等到执行过程中运行到改行代码才停止。

三种检查方式
静态检查:程序运行前自动发现错误。            
动态检查:在执行代码时自动发现错误。            
没有检查:语言根本帮不了你发现错误。你必须自己去看,否则就会有错误的答案。
静态捕捉bug比动态捕捉bug要好,动态捕捉bug要比不捕获bug要好。

静态检查可以捕获的错误     
语法错误,如额外标点或错误的单词。即使是像Python这样的动态类型的语言都会进行这种静态检查            
错误的名字,比如Math.sine(2)
错误的参数数量,比如Math.sin(30, 20)            
错误的参数类型,比如Math.sin(“30”)            
错误的返回类型,如从一个返回int的函数返回“30”。            

动态检查可以捕获的错误       
非法参数值。例如,当y实际上为零时,整型表达式x /y是错误的,否则它会正常运行。因此,在这个表达式中,除以零不是一个静态错误,而是一个动态错误。             
无法表示的返回值,特定的返回值不能被返回类型代表。            
超出范围的索引,例如在字符串上使用负或太大的索引。           
调用null对象引用上的方法。         
    

静态检查倾向于关于类型和错误,这些错误与变量的特定值无关。类型是一组值。静态类型确保变量将从该集合中获得一些值,但直到运行时才知道它的值是多少。因此,如果错误只由某些值引起,如除以零或索引超出范围,那么编译器就不会引发关于它的静态错误与此相反,动态检查往往是由特定值引起的错误。

在Java中存在一些陷阱,和其他的许多编程语言一样,原始数据类型并不是真正的数字。例如:在整数除法中,5/2不返回一个分数,而是返回一个截断整数。int和long类型实际上是整数的有限集,具有最大值和最小值。当计算的答案绝对值太大时,可能会发生计算结果悄悄地溢出所能表示的范围,并从合法范围内的某个地方返回一个整数,但不是正确的答案。

方法 

在Java中,语句一般都包含在一个方法之中,每一个方法都必须包含在某个类里面。方法的修饰词由public,private等,public意味着在程序中的任何地方的代码都可以引用该类或方法。private用于在程序中获得更多的安全,并保证不可变类型的不变性。static意味着这个方法不需要依赖对象进行调用,而且不能被对象调用。

在Java的方法之前,还有一段注释,它是该方法的规约,描述操作的输入和输出。规范应简明、清晰、准确,并且提供方法类型中尚未明确的信息

快照图

画出在运行时发生的事情对我们很有帮助,可以方便我们了解微妙的问题。快照图表示运行时程序的内部状态。

在最简单的形式中,快照图显示每个变量,箭头指向其值。一个值可能是一个原始类型,如int,或者它可能是一个对象类型的字符串或ArrayList,显示为一个带有类型名字的椭圆。一个对象值通常有自己的内部变量,箭头指向它们的值。

快照图提供了一种可视化改变变量和更改值之间的区别的方法           
当你赋值给变量时,你会改变变量箭头的位置。您可以将其指向不同的值。

当更改可变值的内容(如数组或列表)时,将更改该值内的引用。

重新分配与不可变的值

字符串是不可变类型的一个例子,它的值在创建后就永远不会改变,不可变对象在快照图中用双边界表示。

相比之下,StringBuilder是一个可变对象,代表一系列字符的字符串,通常有一些操作改变他的值

java也提供了不变的引用:即被分配之后不会再被重新分配。要使引用不可变,用关键字final声明它,在快照图中,一个不可变引用(最终)用双箭头表示。
                                                                      

注意,我们可以用final关键字修饰可变值。例如:使用final关键字修饰的StringBuilder sb。这意味着,StringBuilder值可以改变,但sb的指向不能改变,它必须始终指向同一个StringBuilder对象。 我们也可以对一个不可变的值(如String s)进行可变引用,在这种情况下,s变量的值可以更改,因为它可以重新指向另一个对象。

 写下一个变量的类型相当于提出一个假设:int n 意味着n总是指一个整数,而不是一个字符串或列表或任何其他类型。java在编译时间实检查这个假设,确保在你的程序中没有地方违反这个假设。

编程的两个目标             

与计算机交流。说服编译器我写的程序是合理的,即语法和类型都正确,从而达到逻辑正确并在运行时给出正确的结果。             

与他人交流。使程序易于理解,以便当有人需要修复它,改进它,或者在将来使用它时,他们可以这样做。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值