第3章标识符与简单数据类型

视频讲解



主要内容 
 标识符与关键字; 
 简单数据类型; 
 简单数据类型的级别与类型转换运算; 
 从命令行窗口输入、输出数据。

本章学习Java中的简单数据类型(基本数据类型),这些简单数据类型和C语言中的简单数据类型很相似,但读者务必也要注意和C语言的不同之处,特别是float常量的格式与C语言的区别。


视频讲解


3.1标识符与关键字
3.1.1标识符

用来标识类名、变量名、方法名、类型名、数组名、文件名的有效字符序列称为标识符。简单地说,标识符就是一个名字。以下是Java关于标识符的语法规则。
 标识符由字母、下画线、美元符号和数字组成,长度不受限制。
 标识符的第一个字符不能是数字字符。
 标识符不能是关键字(关键字见3.1.2节)。
 标识符不能是true、false和null(尽管true、false和null不是Java关键字)。
例如,以下都是标识符: 

HappyNewYear_java、TigerYear_2010、$98apple、Hello.java


需要特别注意的是,标识符中的字母是区分大小写的,hello和Hello是不同的标识符。
Java语言使用Unicode标准字符集,Unicode字符集由UNICODE协会管理并进行技术上的修改,最多可以识别65536个字符,Unicode字符集的前128个字符刚好是ASCII码表。Unicode字符集还不能覆盖全部历史上的文字,但大部分国家的“字母表”的字母都是Unicode字符集中的一个字符,例如汉字中的“好”字就是Unicode字符集中的第22909个字符。Java所谓的字母包括了世界上大部分语言中的“字母表”,因此,Java使用的字母不仅包括通常的拉丁字母a、b、c等,也包括汉语中的汉字、日文的片假名和平假名、朝鲜文、俄文、希腊字母以及其他许多语言中的文字。
 3.1.2关键字
关键字是Java语言中已经被赋予特定意义的一些单词。不可以把关键字作为标识符来用。以下是Java的50个关键字。
abstract assert boolean break byte case catch char class const continue default do double else enum extends final finally float for goto if implements import instanceof int interface long native new package private protected public return short static strictfp super switch synchronized this throw  throws transient try void volatile while






视频讲解



3.2简单数据类型
简单数据类型也称作基本数据类型。Java语言有8种简单数据类型,分别是
boolean、byte、short、int、long、float、double和char。
这8种简单数据类型习惯上可分为以下四大类型。
逻辑类型: boolean。
整数类型: byte、short、int、long。
字符类型: char。
浮点类型: float、double。
 3.2.1逻辑类型
 常量: true、false。
 变量: 使用关键字boolean声明逻辑变量,声明时也可以赋给初值,例如: 

boolean x,ok=true,关闭=false;


 3.2.2整数类型
整型数据分为4种。
1. int型
 常量: 123、6000(十进制),077(八进制),0x3ABC(十六进制)。
 变量: 使用关键字int声明int型变量,声明时也可以赋给初值,例如: 

int x = 12,y = 9898,z;


对于int型变量,内存分配4字节(4B),因此,int型变量的取值范围是-231~231-1。
2. byte型
 变量: 使用关键字byte声明byte型变量,例如: 

byte x=-12,tom=28,漂亮=98;


 常量: Java中不存在byte型常量的表示法,但可以把一定范围内的int型常量赋值给byte型变量。对于byte型变量,内存分配1字节,占8位,因此byte型变量的取值范围是-27~27-1。如果需要强调一个整数是byte型数据时,可以使用强制转换运算的结果表示,例如(byte)-12、(byte)28。
3. short型
 变量: 使用关键字short声明short型变量,例如: 

short x=12,y=1234;


 常量: 和byte型类似,Java中也不存在short型常量的表示法,但可以把一定范围内的int型常量赋值给short型变量。对于short型变量,内存分配2字节,占16位,因此short型变量的取值范围是-215~ 215-1。如果需要强调一个整数是short型数据时,可以使用强制转换运算的结果表示,例如(short)-12、(short)28。
4. long型
 常量: long型常量用后缀L表示,例如108L(十进制)、07123L(八进制)、0x3ABCL(十六进制)。
 变量: 使用关键字long声明long型变量,例如: 

long width=12L,height=2005L,length;


对于long型变量,内存分配8字节,占64位,因此long型变量的取值范围是-263~263-1。
 3.2.3字符类型
 常量: ‘A’、‘b’、‘?’、‘!’、‘9’、‘好’、‘\t’、‘き’、‘モ’等,即用单引号括起的Unicode表中的一个字符。
 变量: 使用关键字char声明char型变量,例如: 

char ch='A',home='家',handsome='酷';

对于char型变量,内存分配2字节,占16位,最高位不是符号位,没有负数的char。char型变量的取值范围是0~65535。对于

char x='a';


那么内存x中存储的是97,97是字符a在Unicode表中的排序位置。因此,允许将上面的语句写成

char x=97;


有些字符(如回车符)不能通过键盘输入字符串或程序中,这时就需要使用转义字符常量,例如
\n(换行)、\b(退格)、\t(水平制表)、\'(单引号)、\"(双引号)、\\(反斜线)等。
例如: 

char ch1='\n',ch2='\"',ch3='\\';


再如,字符串“我喜欢使用双引号\"”中含有双引号字符,但是如果写成: “我喜欢使用双引号"”,就是一个非法字符串。
要观察一个字符在Unicode表中的顺序位置,可以使用int型显式转换,如(int)'a'或int p='a'。如果要得到一个0~65536的数代表的Unicode表中相应位置上的字符,必须使用char型显式转换。
在例3.1中,分别用显式转换显示一些字符在Unicode表中的位置,以及在Unicode表中某些位置上的字符,运行效果如图3.1所示。


图3.1显示Unicode表

中的字符


【例3.1】
Example3_1.java

public classExample3_1 {

public static void main (String args[ ]) {

char chinaWord='好',japanWord='ぁ';

int position=20320;

System.out.println("汉字:"+chinaWord+"的位置:"+(int)chinaWord);

System.out.println("日文:"+japanWord+"的位置:"+(int)japanWord);

System.out.println(position+"位置上的字符是:"+(char)position);

position=21319;

System.out.println(position+"位置上的字符是:"+(char)position); 

}

}


 3.2.4浮点类型
浮点型分为float型和double型。
1. float型
 常量: 453.5439f、21379.987F、231.0f(小数表示法),2e40f(2乘10的40次方,指数表示法)。需要特别注意的是: 常量后面必须有后缀f或F。
 变量: 使用关键字float声明float型变量,例如: 

float x=22.76f,tom=1234.987f,weight=1e-12F;


float变量在存储float型数据时保留8位有效数字,实际精度取决于具体数值。例如,如果将常量12345.123456789f赋值给float型变量x: 

x=12345.123456789f


那么,x存储的实际值是12345.123046875(保留8位有效数字)。
对于float型变量,内存分配4字节,占32位,float型变量的取值范围是10-38~1038和-1038~-10-38。
2. double型
 常量: 2389.539d、2318908.987、0.05(小数表示法),1e-90(1乘10的-90次方,指数表示法)。对于double常量,后面可以有后缀d或D,但允许省略该后缀。
 变量: 使用关键字double声明double型变量,例如: 

double height=23.345,width=34.56D,length=1e12;


double型变量在存储double型数据时保留16位有效数字,实际精度取决于具体数值。
对于double型变量,内存分配8字节,占64位,double型变量的取值范围是10-308~10308和-10308~-10-308。
在例3.2中有两个类,其中,People类具有刻画人的年龄和体重的简单类型变量,主类Example3_2负责用People类创建两个对象。程序运行效果如图3.2所示。


图3.2体重和年龄

【例3.2】
People.java

public class People {

int age;

float weight;

void speak() { 

System.out.println("我的年龄:"+age+"岁");

System.out.println("我的体重:"+weight+"公斤");

}

}

Example3_2.java

public class Example3_2 {

public static void main (String args[ ]) {

People zhang,zhou;

zhang = new People();

zhang.weight=66.5F;

zhang.age=21;

zhang.speak();

zhou = new People();

zhou.weight=56.9F;

zhou.age=19;

zhou.speak();

}

}



视频讲解



3.3简单数据类型的级别与类型转换运算
当把一种基本数据类型变量的值赋给另一种基本类型变量时,就涉及数据类型转换。下列基本类型会涉及数据类型转换(不包括逻辑类型),将这些类型按精度从低到高排列为: 

byteshortcharintlongfloatdouble

当把级别低的变量的值赋给级别高的变量时,系统自动完成数据类型的转换。例如: 

float x=100;


如果输出x的值,结果将是100.0。
例如: 

int x=50;

float y;

y=x;

如果输出y的值,结果将是50.0。
当把级别高的变量的值赋给级别低的变量时,必须使用显式类型转换运算。显式转换的格式: 

(类型名) 要转换的值;

例如: 

int x=(int)34.89;

long y=(long)56.98F;

int z=(int)1999L;


输出x、y和z的值将是34、56和1999,强制类型转换运算可能导致精度的损失。
当把一个int型常量赋值给一个byte型和short型变量时,不可超出这些变量的取值范围,否则必须进行类型转换运算。例如,常量128属于int型常量,超出byte变量的取值范围,如果赋值给byte型变量,必须进行byte类型转换运算(将导致精度的损失),如下所示。

byte a=(byte)128;

byte b=(byte)(-129);


那么,a和b得到的值分别是-128和127。
另外,一个常见的错误是把一个double型常量赋值给float型变量时没有进行强制类型转换运算,例如: 

float x=12.4;


将导致语法错误,编译器将提示“possible loss of precision”。正确的写法是: 

float x=12.4F


或

float x=(float)12.4;



图3.3类型转换运算

例3.3使用了类型转换运算,运行效果如图3.3所示。
【例3.3】
Example3_3.java

public class Example3_3 { 

public static void main (String args[]) {

byte b = 22; 

intn = 129;

float f =123456.6789f ;

double d=123456789.123456789;

System.out.println("b="+b);

System.out.println("n="+n);

System.out.println("f="+f);

System.out.println("d="+d); 

b=(byte)n;//导致精度的损失

f=(float)d;//导致精度的损失

System.out.println("b="+b);

System.out.println("f="+f); 

}

}



视频讲解



3.4从命令行窗口输入、输出数据
3.4.1输入基本型数据

Scanner是JDK 1.5新增的一个类,可以使用该类创建一个对象。

Scanner reader=new Scanner(System.in);


然后reader对象调用下列方法,读取用户在命令行(例如MSDOS窗口)输入的各种基本类型数据。
nextBoolean(),nextByte(),nextShort(),nextInt(),nextLong(),nextFloat(),nextDouble()。

上述方法执行时都会堵塞,程序等待用户在命令行输入数据并回车确认。


图3.4从命令行输入数据

例3.4中用到了例3.2中的People类。例3.4中的主类中用People类创建zhangSan对象,并要求用户依次输入zhangSan对象的年龄和体重,每输入一个数都需要按回车键确认。运行效果如图3.4所示。
【例3.4】
Example3_4.java

import java.util.Scanner;

public class Example3_4 {

public static void main(String args[]) {

People zhangSan = new People();

Scanner reader = new Scanner(System.in);

System.out.println("输入年龄,回车确认");

zhangSan.age = reader.nextInt();

System.out.println("输入体重,回车确认");

zhangSan.weight = reader.nextFloat();

zhangSan.speak();

}

}


 3.4.2输出基本型数据
System.out.println()或System.out.print()可输出串值、表达式的值,二者的区别是前者输出数据后换行,后者不换行。允许使用并置符号“+”将变量、表达式或一个常数值与一个字符串并置一起输出,例如: 

System.out.println(m+"个数的和为"+sum);

System.out.println(":"+123+"大于"+122)。


需要特别注意的是,在使用System.out.println()或System.out.print()输出字符串常量时,不可以出现“回车”,例如,下面的写法无法通过编译: 

System.out.println("你好,

很高兴认识你" );

如果需要输出的字符串的长度较长,可以将字符串分解成几部分,然后使用并置符号“+”将它们首尾相接。例如,以下是正确的写法: 

System.out.println("你好,"+

"很高兴认识你" );


另外,JDK 1.5新增了和C语言中printf函数类似的数据输出方法,该方法使用格式如下: 

System.out.printf("格式控制部分",表达式1,表达式2,…,表达式n)

格式控制部分由格式控制符号%d、%c、%f、%s和普通的字符组成,普通字符原样输出。格式符号用来输出表达式的值。
%d: 输出int类型数据值。
%c: 输出char型数据。
%f: 输出浮点型数据,小数部分最多保留6位。
%s: 输出字符串数据。
输出数据时也可以控制数据在命令行的位置,例如: 
%md: 输出的int型数据占m列。
%m.nf: 输出的浮点型数据占m列,小数点保留n位。

例如: 

System.out.printf("%d,%f",12,23.78);

3.5上机实践
3.5.1输出希腊字母

1. 实验目的
掌握char型数据和int型数据之间的互相转换,了解Unicode标准字符集。
2. 实验要求
编写一个Java应用程序,该程序在命令行窗口输出希腊字母表。
3. 程序模板
请按照模板要求,将【代码1】、【代码2】和【代码3】替换为Java程序代码。
GreekAlphabet.java

public class GreekAlphabet {

public static void main (String args[ ]) {

int startPosition=0,endPosition=0;

char cStart='α',cEnd='ω';

【代码1】//cStart做int型转换运算,并将结果赋值给startPosition

【代码2】//cEnd做int型转换运算,并将结果赋值给endPosition   

System.out.println("希腊字母\'α\'在unicode表中的顺序位置:"+startPosition);

System.out.println("希腊字母表:");

for(int i=startPosition;i<=endPosition;i++) {

char c='\0';

【代码3】  //i做char型转换运算,并将结果赋值给c

System.out.print(" "+c);

if((i-startPosition+1)%10==0)

System.out.println("");  

}

}

}

4. 实验指导
1) 使用软键盘 
编辑源文件时,通过打开软键盘,选择希腊字母选项输入希腊字母。为了输出希腊字母表,首先获取希腊字母表的第一个字母和最后一个字母在Unicode表中的位置,然后循环输出其余的希腊字母。要观察一个字符在Unicode字符集中的顺序位置,必须使用int类型转换。

2) 参考答案
【代码1】: startPosition=(int)cStart;
【代码2】: endPosition=(int)cEnd;
【代码3】: c=(char)i;
5. 实验后的练习
(1) 将一个double型数据直接赋值给float型变量,程序编译时提示怎样的错误?
(2) 在main方法中增加语句“float x = 0.618;”,程序能编译通过吗?
(3) 在main方法中增加语句“byte y = 128;”,程序能编译通过吗?在 main方法中增加语句“int z = (byte)128;”,程序输出变量z的值是多少?
 3.5.2产品的总价
1. 实验目的
掌握从键盘为简单型变量输入数据。掌握使用Scanner类创建一个对象,例如: 

Scanner reader=new Scanner(System.in);


学习让reader对象调用下列方法读取用户在命令行(例如MSDOS窗口)输入的各种简单类型数据: 
nextBoolean(),nextByte(),nextShort(),nextInt(),nextLong(),nextFloat(),nextDouble()
在调试程序时,体会上述方法都会出现堵塞状态,即程序等待用户在命令行输入数据并回车确认。
2. 实验要求
编写一个Java应用程序,在主类的main方法中声明用于存放产品数量的int型变量amount和产品单价的float型变量,以及存放全部产品总价值的float型变量sum。
使用Scanner对象调用方法让用户从键盘为amount、price变量输入值,然后程序计算出全部产品的总价值,并输出amount、price、sum的值。程序运行参考效果如图3.5所示。


图3.5从键盘输入数据

3. 程序模板
请按照模板要求,将【代码1】和【代码2】替换为Java程序代码。
InputData.java

import java.util.Scanner;

public class InputData {

public static void main(String args[]) {

Scanner reader=new Scanner(System.in);  

int amount =0 ;   

float price=0,sum=0;

System.out.println("输入产品数量(回车确认):");

【代码1】 //从键盘为amount赋值

System.out.println("输入产品单价(回车确认):");

【代码2】 //从键盘为price赋值

sum = price*amount;

System.out.printf("数量:%d,单价:%5.2f,总价值:%5.2f",amount,price,sum);

} 

}

4. 实验指导
1) 几个常用方法
Scanner对象可以调用hasNextXXX()方法判断用户输入的数据的类型,例如,如果用户从键盘输入带小数点的数字“12.34(回车)”,那么reader对象调用hasNextDouble()返回的值是true,而调用hasNextByte()、hasNextInt()以及hasNextLong()返回的值都是false; 如果用户从键盘输入一个byte取值范围内的整数“89(回车)”,那么reader对象调用hasNextByte()、hasNextInt()、hasNextLong()以及hasNextDouble()返回的值都是true。nextLine()等待用户在命令行输入一行文本并回车确认,该方法得到一个String类的数据,String类将在第9章讲述。在从键盘输入数据时,经常让reader对象先调用hasNextXXX()方法等待用户从键盘输入数据,然后再调用nextXXX()方法读取数据。
2) 参考答案
【代码1】: amount = reader.nextInt();
【代码2】: price = reader.nextFloat();
5. 实验后的练习
上机调试下列程序。该程序可以让用户从键盘依次输入若干个数,每输入一个数都需要按回车键确认,最后用户从键盘输入一个非数字字符结束整个输入操作过程(用户输入非数字字符后reader.hasNextDouble()的值将是false)。程序将计算出这些数的和以及平均值。

import java.util.*;

public class LianXi{

public static void main (String args[ ]){

Scanner reader=new Scanner(System.in);

double sum=0;

int m=0;

while(reader.hasNextDouble()){

double x=reader.nextDouble();

m=m+1;

sum=sum+x;

}

System.out.printf("%d个数的和为%f\n",m,sum);

System.out.printf("%d个数的平均值是%f\n",m,sum/m); 

}

}


3.6课外读物
课外读物均来自编者的教学辅助微信公众号javaviolin,扫描二维码即可学习观看。
计算机中为什么0.4F≠0.4D?


课外读物


习题
1. 什么是标识符?标识符的规则是什么?true是否可以作为标识符?
2. 什么是关键字?true和false是否为关键字?请写出6个关键字。
3.  Java的基本数据类型都是什么?
4. 上机运行下列程序,注意观察输出的结果。

public class E {

public static void main (String args[ ]) {

for(int i=20302;i<=20322;i++) {

System.out.println((char)i);

}

}

}

5. 上机调试下列程序,注意System.out.print()和System.out.println()的区别。

public class OutputData { 

public static void main(String args[]) {

int x=234,y=432; 

System.out.println(x+"<"+(2*x)); 

System.out.print("我输出结果后不回车"); 

System.out.println("我输出结果后自动回车到下一行");

System.out.println("x+y= "+(x+y));

}

}


6. 编写一个Java应用程序,输出全部的大写英文字母。
7. 是否可以将例3.4中的
“zhangSan.weight = reader.nextFloat();”

更改为

“zhangSan.weight = reader.nextDouble();”?