友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
一世书城 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

Java编程思想第4版[中文版](PDF格式)-第38章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!






                                                                               72 


…………………………………………………………Page 74……………………………………………………………

当然要比键入两个简单。在Java 里,编译器同样可防止这一点,因为它不允许我们强行使用一种并不属于的 

类型。  



3。1。13  造型运算符  



 “造型”(Cast )的作用是“与一个模型匹配”。在适当的时候,Java 会将一种数据类型自动转换成另一 

种。例如,假设我们为浮点变量分配一个整数值,计算机会将 int 自动转换成float。通过造型,我们可明 

确设置这种类型的转换,或者在一般没有可能进行的时候强迫它进行。  

为进行一次造型,要将括号中希望的数据类型(包括所有修改符)置于其他任何值的左侧。下面是一个例 

子:  

  

void casts() {  

int i = 200;  

long l = (long)i;  

long l2 = (long)200;  

}  

  

正如您看到的那样,既可对一个数值进行造型处理,亦可对一个变量进行造型处理。但在这儿展示的两种情 

况下,造型均是多余的,因为编译器在必要的时候会自动进行 int值到 long 值的转换。当然,仍然可以设置 

一个造型,提醒自己留意,也使程序更清楚。在其他情况下,造型只有在代码编译时才显出重要性。  

在C 和C++中,造型有时会让人头痛。在Java 里,造型则是一种比较安全的操作。但是,若进行一种名为 

 “缩小转换”(Narrowing Conversion)的操作(也就是说,脚本是能容纳更多信息的数据类型,将其转换 

成容量较小的类型),此时就可能面临信息丢失的危险。此时,编译器会强迫我们进行造型,就好象说: 

 “这可能是一件危险的事情——如果您想让我不顾一切地做,那么对不起,请明确造型。”而对于“放大转 

换”(Widening conversion),则不必进行明确造型,因为新类型肯定能容纳原来类型的信息,不会造成任 

何信息的丢失。  

Java 允许我们将任何主类型“造型”为其他任何一种主类型,但布尔值(bollean)要除外,后者根本不允 

许进行任何造型处理。“类”不允许进行造型。为了将一种类转换成另一种,必须采用特殊的方法(字串是 

一种特殊的情况,本书后面会讲到将对象造型到一个类型“家族”里;例如,“橡树”可造型为“树”;反 

之亦然。但对于其他外来类型,如“岩石”,则不能造型为“树”)。  

  

1。 字面值  

最开始的时候,若在一个程序里插入“字面值”(Literal),编译器通常能准确知道要生成什么样的类型。 

但在有些时候,对于类型却是暧昧不清的。若发生这种情况,必须对编译器加以适当的“指导”。方法是用 

与字面值关联的字符形式加入一些额外的信息。下面这段代码向大家展示了这些字符。  

  

//: Literals。java  

  

class Literals {  

  char c = 0xffff; // max char hex value  

  byte b = 0x7f; // max byte hex value  

  short s = 0x7fff; // max short hex value  

  int i1 = 0x2f; // Hexadecimal (lowercase)  

  int i2 = 0X2F; // Hexadecimal (uppercase)  

  int i3 = 0177; // Octal (leading zero)  

  // Hex and Oct also work with long。  

  long n1 = 200L; // long suffix  

  long n2 = 200l; // long suffix  

  long n3 = 200;  

  //! long l6(200); // not allowed  

  float f1 = 1;  

  float f2 = 1F; // float suffix  

  float f3 = 1f; // float suffix  



                                                                                    73 


…………………………………………………………Page 75……………………………………………………………

  float f4 = 1e…45f; // 10 to the power  

  float f5 = 1e+9f; // float suffix  

  double d1 = 1d; // double suffix  

  double d2 = 1D; // double suffix  

  double d3 = 47e47d; // 10 to the power  

} ///:~  

  

十六进制(Base 16)——它适用于所有整数数据类型——用一个前置的 0x 或 0X 指示。并在后面跟随采用大 

写或小写形式的0…9 以及a…f。若试图将一个变量初始化成超出自身能力的一个值(无论这个值的数值形式 

如何),编译器就会向我们报告一条出错消息。注意在上述代码中,最大的十六进制值只会在char,byte 以 

及 short 身上出现。若超出这一限制,编译器会将值自动变成一个 int,并告诉我们需要对这一次赋值进行 

 “缩小造型”。这样一来,我们就可清楚获知自己已超载了边界。  

八进制(Base 8)是用数字中的一个前置0 以及0…7 的数位指示的。在 C,C++或者Java 中,对二进制数字 

没有相应的“字面”表示方法。  

字面值后的尾随字符标志着它的类型。若为大写或小写的 L,代表 long;大写或小写的F,代表 float;大写 

或小写的D,则代表double。  

指数总是采用一种我们认为很不直观的记号方法:1。39e…47f。在科学与工程学领域,“e”代表自然对数的 

基数,约等于2。718 (Java 一种更精确的double 值采用 Math。E 的形式)。它在象“1。39 ×e 的…47 次方”这 

样的指数表达式中使用,意味着“1。39×2。718 的…47 次方”。然而,自 FORTRAN 语言发明后,人们自然而然 

地觉得 e 代表“10多少次幂”。这种做法显得颇为古怪,因为FORTRAN 最初面向的是科学与工程设计领域。 

理所当然,它的设计者应对这样的混淆概念持谨慎态度(注释①)。但不管怎样,这种特别的表达方法在 

C,C++以及现在的Java 中顽固地保留下来了。所以倘若您习惯将 e 作为自然对数的基数使用,那么在 Java 

中看到象“1。39e…47f”这样的表达式时,请转换您的思维,从程序设计的角度思考它;它真正的含义是 

 “1。39×10 的…47 次方”。  

  

①:John Kirkham 这样写道:“我最早于 1962 年在一部 IBM 1620 机器上使用 FORTRAN II。那时——包括 

60 年代以及 70 年代的早期,FORTRAN 一直都是使用大写字母。之所以会出现这一情况,可能是由于早期的输 

入设备大多是老式电传打字机,使用5 位Baudot 码,那种码并不具备小写能力。乘幂表达式中的‘E’也肯 

定是大写的,所以不会与自然对数的基数‘e’发生冲突,后者必然是小写的。‘E’这个字母的含义其实很 

简单,就是‘Exponential’的意思,即‘指数’或‘幂数’,代表计算系统的基数——一般都是 10。当 

时,八进制也在程序员中广泛使用。尽管我自己未看到它的使用,但假若我在乘幂表达式中看到一个八进制 

数字,就会把它认作Base 8。我记得第一次看到用小写‘e’表示指数是在70 年代末期。我当时也觉得它极 

易产生混淆。所以说,这个问题完全是自己‘潜入’FORTRAN 里去的,并非一开始就有。如果你真的想使用 

自然对数的基数,实际有现成的函数可供利用,但它们都是大写的。”  

  

注意如果编译器能够正确地识别类型,就不必使用尾随字符。对于下述语句:  

long n3 = 200;  

它并不存在含混不清的地方,所以 200 后面的一个 L 大可省去。然而,对于下述语句:  

float f4 = 1e…47f; //10 的幂数  

编译器通常会将指数作为双精度数(double)处理,所以假如没有这个尾随的 f,就会收到一条出错提示, 

告诉我们须用一个“造型”将 double 转换成 float。  

  

2。 转型  

大家会发现假若对主数据类型执行任何算术或按位运算,只要它们“比 int小”(即 char,byte 或者 

short),那么在正式执行运算之前,那些值会自动转换成int。这样一来,最终生成的值就是int类型。所 

以只要把一个值赋回较小的类型,就必须使用“造型”。此外,由于是将值赋回给较小的类型,所以可能出 

现信息丢失的情况)。通常,表达式中最大的数据类型是决定了表达式最终结果大小的那个类型。若将一个 

float 值与一个double值相乘,结果就是 double;如将一个 int和一个 long 值相加,则结果为 long。  



3。1。14 Java 没有“sizeof ”  



在C 和C++中,sizeof()运算符能满足我们的一项特殊需要:获知为数据项目分配的字符数量。在C 和C++ 

中,size()最常见的一种应用就是“移植”。不同的数据在不同的机器上可能有不同的大小,所以在进行一 



                                                                          74 


…………………………………………………………Page 76……………………………………………………………

些对大小敏感的运算时,程序员必须对那些类型有多大做到心中有数。例如,一台计算机可用32 位来保存整 

数,而另一台只用 16 位保存。显然,在第一台机器中,程序可保存更大的值。正如您可能已经想到的那样, 

移植是令C 和C++程序员颇为头痛的一个问题。  

Java 不需要 sizeof()运算符来满足这方面的需要,因为所有数据类型在所有机器的大小都是相同的。我们不 

必考虑移植问题——Java 本身就是一种“与平台无关”的语言。  



3。1。15  复习计算顺序  



在我举办的一次培训班中,有人抱怨运算符的优先顺序太难记了。一名学生推荐用一句话来帮助记忆: 

 “Ulcer Addicts Really Like C A lot”,即“溃疡患者特别喜欢(维生素)C”。  

  

助记词 运算符类型 运算符  

  

Ulcer (溃疡) Unary:一元 + + + '' 其余的 ''  

Addicts (患者) Arithmetic(shift) ;算术(和移位) * / % + 》  

Really (特别) Relational:关系 》 《 》= B ? X:Y  

A Lot Assignment:赋值 = (以及复合赋值,如*=)  

  

当然,对于移位和按位运算符,上表并不是完美的助记方法;但对于其他运算来说,它确实很管用。  



3。1。16  运算符总结  



下面这个例子向大家展示了如何随同特定的运算符使用主数据类型。从根本上说,它是同一个例子反反复复 

地执行,只是使用了不同的主数据类型。文件编译时不会报错,因为那些会导致错误的行已用//!变成了注释 

内容。  

  

//: AllOps。java  

// Tests all the operators on all the  

// primitive data types to sh
返回目录 上一页 下一页 回到顶部 0 0
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!