课程导学
你好,欢迎回来,我是彭彭!HAKUNA MATATA!!!
在我们接受启蒙教育的时候,我们学习认识身边的事物,比如桌子、椅子、米饭、碗......到了学校,老师教我们认识文字、数数以及四则运算。现在,我带你穿越回那个充满好奇和求知欲的时代,再做一回小学生,重新温习我们对这个世界最初的认识。
从这节课开始,正式进入 Java 语言的核心语法部分。这节课为你介绍如何使用 Java 语言描述生活中的数据、符号,下节课介绍如何进行数据运算。这是对 Java 语言最基本的使用,通过本节课的学习,我将带你初步体验现实生活与编程语言是如何联系在一起的。
通过本节课程,你将学到如下内容:
- 生活中有哪些数据,它们有哪些分类?
- 怎样使用 Java 语言描述生活中的数据?
要想顺利学会本课的知识,你需要具备这种水平的知识储备:小学学历。我猜你肯定拥有这么“高”的学历,希望我猜的没错 ^_^。
以下是课程目录:
- 第一关 变量:看我七十二变
- 第二关 数据类型:如来的手掌心
- 第三关 常量:永恒的力量
- 第四关 标识符:有名,万物之母
第一关 变量:看我七十二变
生活中有大量的数据,比如水果的颜色:蓝色(蓝莓),红色(红提),绿色(青苹果);比如性别:男、女;比如光在真空中的速度:3 * 10 ^8米/秒;比如自然数:1、2、10、20;还有圆周率 π :3.1415926...
数据的种类各不相同,有的是数值,有的是文字,但它们都能代表某种信息。如果我们想要用 Java 语言描述这些数据,该怎么做呢?思考一下,我们要描述清楚一个数据,需要弄明白哪些要素?就拿水果的颜色来说:
- 要描述什么数据:颜色(color)
- 数据的值是什么:可能是蓝色、红色、绿色等等
- 数据是什么类型(数据的表现形式)的:一串文字 (String)
在我们编写代码时,除了数据的值,其它情况下,一般 尽可能避免 使用中文,所以,我们用英文color
表示颜色,用String
表示一串文字。
现在,弄清楚了这三要素,我们就可以使用 Java 语言来描述水果的颜色了:
public class Test{
public static void main(String[] args) {
String color = "蓝色"; // 蓝莓的颜色
System.out.println(color); // 使用输出语句,打印出蓝色
}
}
输出结果:
蓝色
上面的代码完成了一个变量的声明,也就是创建了一个变量。接下来,我们深入的认识一下这行代码:
String color = "蓝色"; // 蓝莓的颜色
- color:要描述的数据的名称,称为
变量名
。一般用一个或多个英文单词表示,最好是让人一看就知道它表示的数据的含义。 - 蓝色:要描述的数据的值,称为
变量值
或初始化值
。如果变量值是一串文字,需要用双引号("")将值包起来。 - String:要描述的数据的表现形式,称为
数据类型
。表示一串文字或一句话时,用这个类型。 - = 号:赋值符号(本节第二部分介绍),表示后面是具体的数据值。
- 这行代码被称为一条语句,每个语句都应该以分号(;)结束。
那么,为什么叫 “变量” ?
顾名思义,就是可能会发生变化的数据。从这行代码上看,color
代表水果的颜色,现在的取值是“蓝色”,难道所有的水果都是蓝色的吗?它也有可能是红色、绿色、黄色等等,也就是说,水果的颜色是一个有可能会发生变化的数据,所以,“水果的颜色”这个数据,是一个变量。
照这么说,人们的性别也是一个变量,尽管它的变化范围很小:
String sex = "男"; // 人们的性别,可能是男、女。还有其它可能?
现在,我心里有一个数字,你猜猜看。。。。可能是1,可能是10,也可能是0、7、100、999....可能是任意数字,无论你猜什么,我都会说:不对(嘿嘿...)。
怎么定义一个数字变量呢?
还是老规矩,分析一下三要素:
- 变量名:number,表示要猜的数字
- 变量值:10?20?算了,随便给一个吧。
- 数据类型:还用 String 吗?不合适,因为 String 表示一串文字,而不是数字。数字用
int
表示。
好吧,我们试着定义这个变量:
public class Test{
public static void main(String[] args) {
int number = 10; // 猜数字,猜到了10,你也可以写20,5,7,,,
System.out.println(number); // 使用输出语句,打印出数字10
}
}
输出:
10
这里有个值得注意的细节:数字10并没有用双引号包起来。没错,只有文字数据需要双引号,数字数据不需要。
既然变量的值可以发生改变,那就让它千变万化吧(完整代码):
public class Test{
public static void main(String[] args) {
String color = "蓝色"; // 蓝莓的颜色
String sex = "男"; // 人们的性别,可能是男、女。还有其它可能?
int number = 10; // 猜数字,猜到了10,你也可以写20,5,7,,,
System.out.println(color); // 使用输出语句,打印蓝莓的颜色
System.out.println(sex); // 使用输出语句,打印出人们的性别
System.out.println(number); // 使用输出语句,打印出数字10
System.out.println("-----我是华丽的分割线-----");
// 这里要注意,前面不需要加上数据类型了,程序是能够识别已经定义过的变量的类型的
color = "红色"; // 把color修改成红色
number = 20; // 把number修改成20
sex = "女"; // 把sex修改成女
System.out.println(color); // 使用输出语句,打印苹果的颜色
System.out.println(sex); // 使用输出语句,打印出人们的性别
System.out.println(number); // 使用输出语句,打印出数字20
}
}
输出结果:
蓝色
男
10
-----我是华丽的分割线-----
红色
女
20
这里要注意,重新修改变量的值,变量前面不需要数据类型了,只有定义一个变量才需要,使用的时候,程序能够识别它是什么类型哦!
现在,我们来对变量这个知识做个小结。
首先,定义变量是需要遵循一定的格式的:
数据类型 变量名 = 初始化值;
其次,各部分的含义是什么?
- 数据类型:数据的表现形式(数据是什么样的),也是变量的值可以变化的范围,就像悟空的七十二般变化,除此之外的变化,悟空不能变。
- 变量名:每个变量都有一个名字,就像孙悟空无论变成什么,他都是孙悟空。
- 初始化值:即变量值,使用变量前,需要给变量赋予一个值,然后才能使用。悟空的初始名字:美猴王。
最后,在使用变量的时候,可以直接用它的名字进行输出,也可以用它的名字进行运算——稍后介绍,总之,是直接通过变量的名字来使用它,而不是它的具体值,程序运行的时候,根据变量的名字去找到它的值,然后再输出,或者进行其它运算。
考一考:定义变量
查看下图,假设三个图标分别代表的内容是:
- 商品的价格:可能的取值有:5元,6元,4元
- 钟表的时间:5点
- 程序员生涯的职位:可能的取值有:开发工程师,开发经理,项目经理,CTO
请分别定义变量描述图标所代表的数据,并用输出语句打印出来。
参考答案:
public class Test{
public static void main(String[] args) {
int price = 6; // 商品的价格
System.out.println(price);
int time = 5; // 钟表的时间
System.out.println(time);
String position = "CTO"; // 程序员的职位
System.out.println(position);
}
}
输出结果:
6
5
CTO
第二关 数据类型:如来的手掌心
就像猴子飞不出如来佛的手掌心,变量的取值范围也是有限的。数据类型不仅仅是数据的表现形式,也限定了变量值的变化范围。这就好比,当我问你“苹果的价格多少钱一斤?”的时候,你可以回答一个数字,但是不能说“苹果很甜”这样的答案——这不符合逻辑,也不符合人们的常识。所以,苹果的价格就被限定在了“必须是一个数值”这样的范围里:
int price = 6; // 苹果的价格,是6元钱/斤
它必须是数值,而不能是“颜色”、“大小”之类的数据。
眼尖的你可能已经发现,苹果的价格不一定是整数。而事实上,很多商品的价格都不是整数——尤其是商家促销的时候。那么,怎么表示一个浮点数类型的价格呢?Java 语言用 double
和 float
表示浮点数,就像这样:
double price1 = 5.5; // 苹果的价格,是5.5元/斤
或者这样:
float price2 = 2.75; // 苹果的价格,是2.75元/斤
float
就是浮点数的意思,而 double
是双倍的意思,它们有什么联系吗?是的,double
代表“双精度浮点数”,它能表示的精度是 float
类型的两倍。你要是觉得用两种数据类型表示浮点数有些冗余,那看看表示整数的类型有几种:
byte // 字节型,占1个字节,只能表示 -2^7 ~ 2^7 - 1 (即-128 ~ 127)之间的数据
short // 短整型,占2个字节,表示 -2^15 ~ 2^15 - 1 之间的数据
int // 整型,占4个字节,表示 -2^31 ~ 2^31 - 1 之间的数据,大概是正负21亿之间
long // 长整型,占8个字节,表示 -2^63 ~ 2^63 - 1 之间的数据
上面这四种类型都表示整数,他们唯一的区别就是:表示范围不同。自上而下的顺序就是它们所能表示范围从小到大的顺序。
long
和int
都表示整型,而 long
类型的“长”,指的是它能表示比 int
更大的范围。 long
类型占8个字节而int
类型在内存中占用4个字节的空间,所以 long
类型能比 int
存储更大的数值;相反,short
和 byte
类型占用的字节更少,它们能够表示的数值范围更小。float
类型和 double
类型同理。
当我们提到一个整数时,通常我们会认为它是一个 int
类型,所以,int
类型是整数类型的默认类型;同样的,当我们提到一个浮点数时,通常我们会认为是 double
类型,double
类型是浮点数类型的默认类型。
你以为这就完了?年轻!
Java 语言里面除了有表示“一串文字”的字符串类型:String
,还有表示单个字符的数据类型:char
:
char ch = '中';
// 或者,像这样:
char ch2 = 'A';
char
类型表示单个字符,你可以这么理解,它表示世界上几乎所有国家和地区的文字、数字和符号。比如中文的所有汉字、英文的26个字母、0-9的数字、还可以表示罗马数字、俄罗斯语中的字母等等。
除此之外,当我们需要判断事实为真、假的时候,还需要一个能够表示逻辑的数据类型:boolean
。这个类型比较特殊,它只有两个值,表示真和假:true
和 false
:
boolean isTrue = true; // 表示真
// 或者,像这样:
boolean isFalse = false; // 表示假
到此为止,Java 语言中的八种基本数据类型已经全部揭开神秘面纱:
“为什么会产生这么多的数据类型,同一类的数据类型能不能只要一个?”
“额额额,这件事说来话长......”
“那你长话短说。”
“简单来说,设计多种数据类型的目的是为了更充分的利用内存空间,提高内存使用的效率。最初的计算机内存空间都非常小,使用范围较小的数据类型可以节约存储资源,而现在基本上已经不存在这样的问题,所以,那些范围较小的数据类型就不再常用了。”
所以,这八种类型的使用并不要求你全部掌握(如果你真的感兴趣,可以记住它们在内存中所占用的字节数,找到规律更好记哦),有些类型实在是不常用,那么,把最常用的类型拿出来:
int // 整型
long // 长整型
double // 双精度浮点型
boolean // 布尔型
“刚开始使用的字符串类型 String
为什么不在这八种类型之中?”
“ String
是引用数据类型,并不在这八种基本类型之中。你可以把引用类型理解成由多个基本类型组合在一起的复杂数据类型,引用类型数据是程序的重要组成部分,到【面向对象】相关的课程再为你介绍他们到底有什么不同。”
现在,对 Java 语言中的数据类型做个小结。
Java 语言中的数据类型,分为两大类:基本数据类型、引用数据类型。
基本类型又分为四类,共八种:
- 整数型四种:
byte
、short
、int
、long
- 浮点型两种:
float
、double
- 字符型一种:
char
- 布尔型一种:
boolean
整型的默认类型是:int
;浮点型的默认类型是 double
;
引用类型包括:类、接口、枚举等类型,我们前面使用过的 String
类型,就是一个普通的类。
考一考:不同类型的变量定义和使用
请根据下面数据类型与值的对应关系,分别定义不同的变量,并输出它们的值:
long(18)、double(3.14)、boolean(false)、char(@)
答案:
public class Test{
public static void main(String[] args) {
long age = 18; // 永远的18岁
System.out.println(age);
double pai = 3.14; // 圆周率
System.out.println(pai);
boolean nan = false; // 性别男,爱好?
System.out.println(nan);
char email = '@'; // email的特殊符号
System.out.println(email);
}
}
输出结果:
18
3.14
false
@
第三关 常量:永恒的力量
除了变量之外,生活中还有一些不会发生变化的数据,我们称为常量。常量,顾名思义,就是不变的量,也就是不会变化的数据。比如光在真空中的速度是一个常量:3 * 10 ^8 m/s,圆周率也是一个常量:3.1415926...。我们可以直接把它们的值进行输出:
public class Test{
public static void main(String[] args) {
System.out.println(300_000_000); // 输出光在真空中的速度。JDK7以后,可以在数值之间加下划线,便于观察,但不影响数据本身
System.out.println(3.1415926); // 输出圆周率,是一个无限不循环小数,无法穷举
}
}
打印结果:
300000000
3.1415926
相对于变量而言,常量不需要定义就可以直接使用。但是,如果把这两个常量作为变量的值,然后直接输出变量,会发生什么?
public class Test{
public static void main(String[] args) {
int speed = 300_000_000; // 整型,默认使用int
double pai = 3.1415926; // 浮点类型,默认使用double
System.out.println(speed); // 输出光在真空中的速度
System.out.println(pai); // 输出圆周率
}
}
打印结果没有任何变化:
300000000
3.1415926
咦,这不就是定义变量的方式吗?!
没错。上面的代码的确是定义了两个变量,但它们的值,都是常量。也就是说,定义变量的过程,其实是把常量赋值给某一个变量名。换句话说,我们前面定义的变量,它们的值都是常量,而这些常量数据,我们称为字面值常量(字面值:文字表面的值)。像颜色(黄色、红色、绿色)、性别(男、女)、自然数(1,2,10,20)等等,它们都是字面值常量。之所以这么说,是因为这些数据都是人们约定俗成的、不会再更改的。继续引申,所有的颜色、数值、文字等,包括我们现在口中说的话,都是字面值常量。
既然几乎所有数据本身都是"常量",那“变量”与常量之间又有什么关系?
变量是某一范围(常量)数据的抽象描述。
这句话有以下几层含义:
- 一个变量定义之初,就确定了它的值可能发生变化的范围,而该范围中每一个取值,其实都是常量;
- 常量是生活中具体存在的数据,而变量是对这些数据的抽象描述;
- 变量与常量的关系,是抽象描述与具体存在之间的包含关系;
还是以商品价格为例:
double price = 5.5; // 苹果的价格是5.5元/斤
- 变量
price
的取值是一个浮点型常量 5.5,它的取值范围必须是数值,准确地说是double
类型支持的数值范围; - 这里的 5.5 是具体存在的常量数据,而
price
(价格) 是对这个数据的一种描述; - 这里的
price
(价格)可能会发生变化,所以它可以包含很多个常量数据,比如 6.5,4.0,3 等等;
上面介绍的常量,都是字面值常量。当这些数据不足以提供复杂应用的需求时,程序员可以自定义一些常量来使用。在 Java 语言中,使用 final
关键字来自定义常量,也就是说,使用 final
关键字将原来可以变化的数据,修饰成不可变的,就像这样:
// 用 final 修饰变量,则改变量被称为自定义常量,此时 “变量” LIGHT_SPEED 将不能被重新赋值
final double LIGHT_SPEED = 299792458; // 光速,单位m/s
这行代码的意思是,使用关键字 final
修饰变量 LIGHT_SPEED
,那么它不再是可变的,而是作为自定义常量而存在。这就意味着,LIGHT_SPEED
的含义是确定的,只能是 299792458
,不可能是其它值。此时,再尝试修改 LIGHT_SPEED
的值,将会报错:
错误信息的意思是:无法为 final
变量 LIGHT_SPEED
分配值,即 LIGHT_SPEED
不能再一次被赋值。
这就是自定义常量。与字面值常量相比,程序员自己定义的常量,往往比字面值常量复杂。尽管如此,它们都是“常量”,因为它们都有共同的特征:不变,即不会被人为修改。你可能会说,我直接使用数据 299792458
就行了,何必定义 LIGHT_SPEED
这么麻烦呢?事实上,当我们只看到 299792458
这个数据的时候,能直观地理解它的含义吗,毋庸置疑,看到 LIGHT_SPEED
这样的数据更直观,而且,在以后维护代码的时候,也会更方便。
对常量这个知识点做个小结。
Java中的常量分成两大类:字面值常量和自定义常量。自定义常量取决于程序员的需求,种类繁多而且复杂(自定义引用类型常量要比其它种类常量复杂很多,面向对象相关课程介绍)但总归来说就是,使用 final
关键字修饰变量,让变量的值无法被修改。而字面值常量相对简单些,只有 6 种情况:
- 整数常量:比如 1,2,10,20, -1
- 小数(浮点数)常量:比如 3.14,0.618
- 布尔常量:表示
真
或假
,只有两个:true,false - 字符常量:表示单个字符,用单引号包起来,比如 'a' ,'b' ,'c' ,'中' ,'国' ,'@', '-'
- 字符串常量:表示多个字符,用双引号包起来,比如 "Hello world", "你好", "北京欢迎你"
- 空常量:表示数据为空,只有一个值:null,它是引用类型数据的默认值。
常量相关的知识偏重于理解,所以,对你的要求很简单:
- 理解常量的概念和分类
- 能够区分常见的字面值常量
关于字符串常量(选学)
简单介绍下字符串为什么是常量,如果你无法理解这里的知识,建议学完“常用工具(API)”课程,再回过来看这段文字就非常容易了。
字符串数据在 JVM 中以常量的形式存在,每个字符串都是独一无二的(Java 文档中将 String 类对象称为“不可变字符串”)。String 类没有提供用于修改字符串的方法,事实上,也无法修改字符串数据。比如,如果希望将 "Hello"
的内容修改为 "Help!"
,不能直接地将最后两个位置的字符修改为 'p' 和 '!' ,那怎么呢? 在 Java中实现这项操作非常容易,首先提取需要的字符, 然后再拼接上替换的字符串:
"Hello".substring(0, 3) + "p!" // 得到的结果为 Help!
substring()
用于截取一个子字符串。上面代码的意思是,从字符串 "Hello"
中截取一个子串,这个子串是从原字符串索引 0 的位置开始,截取 3 个字符,结果就是 "Hel"
,然后再用字符串连接符(+)与 "p!"
进行拼接,最终结果就是 "Help!"
。
就像数字 3 永远是数字 3 —样, 字符串“ Hello” 永远包含字符 H、 e、 1、 1 和 o 的代码单元序列, 而不能修改其中的任何一个字符。 我们对字符串进行修改的操作,其本质是生成一个新的字符串 "Help!"
,让使用者引用这个新字符串, 这看起来就像可以将存放 3 的数值改成存放 4 一样。
参考完整代码:
public class Test{
public static void main(String[] args) {
String greeting = "Hello";
greeting = "Hello".substring(0, 3) + "p!";
System.out.println(greeting); // Help!
}
}
参考操作示意图:
考一考:认识常量
查看下面的数据,它们是不是常量,若是,请分别指出是什么常量?
"H" "z" '0' -0.3 "null" 'true' 0
答案:
"H"是,字符串;"z"是,字符串;
'0'是,字符;
-0.3是,浮点数;
"null"是,字符串;
'true'不是,语法错误。因为单引号(' ')里面只能包含一个字符,不能有多个;如果要表示多个字符,用双引号("")包起来
0是,整数
解析:'true',它是语法错误。因为单引号(' ')里面只能包含一个字符,不能有多个;如果要表示多个字符,用双引号("")包起来
第四关 标识符:有名,万物之母
无名,天地之始;有名,万物之母——《道德经 · 老子》。这句话的大概意思是说,天地初开的时候,一片混沌,什么都没有,后来生成了万物,人们便给万物命名(欢迎拍砖)。万物的名字,就是人们标注并识别万物的符号,简称标识符。
万物有名,人也不例外,比如父亲张翠山和他的儿子张无忌,都是大名鼎鼎的侠客,“张翠山”和“张无忌”这两个名字,就是他们的标识符。同样,Java 程序的每个部分也有自己的名字,给类、方法、变量、常量等起名字的字符序列,就是标识符。切换成人话,标识符就是在编程中程序员给类、方法、变量、常量等起的名字。看看我们前面定义的变量,它们的名字都是标识符:
public static void main(String[] args) { // main方法的名字:main
long age = 18; // long类型的变量,名字是:age
double pai = 3.14; // double类型的变量,名字是:pai
boolean nan = false; // boolean类型的变量,名字是:nan
char email = '@'; // char类型的变量,名字是:email
boolean isTrue = true; // boolean类型的变量:isTrue
boolean isFalse = false; // boolean类型的变量:isFalse
}
你可以尝试使用中文、韩文、日文等作为变量的名字,运气好的话,应该不会报错^_^:
public static void main(String[] args) {
String 식별자 = "韩语标识符"; // 韩语标识符
String 标识符 = "中文标识符"; // 中文标识符
String identifier = "identifier"; // 英文标识符
}
从理论上讲,编程语言支持的所有国家的文字、数字和符号,都可以作为标识符的组成部分,但是——前面都是废话,习惯上我们不那么做,因为主流编程语言都是用英文写成的。标识符的组成是有要求的,建议只使用下面的字符:
- 英文大小写字母:a - z 和 A - Z
- 数字:0 - 9
- 下划线: _
- 美元符号: $
尽管如此,我们也不能随意定义标识符。按照规则办事,总是能减少很多麻烦。标识符的定义规则:
- 不能以数字开头。为啥,不美观?对,就是不美观。
- 不能是关键字。关键字已经被 Java 语言征用,我们不能再直接拿它们作为标识符了。
- 严格区分大小写。Java 语言是严格区分大小写的——可能就是怕好用的标识符不够用吧,谁知道呢!
这些都是约定俗成的规矩,真的没什么好说的,你要是觉得不爽,可以自己写个编程语言,随自己心意随便改,相信你能行。
好吧,最后一条,也是最重要的:标识符的命名规范:
- 类和接口:首字母大写,如果有多个单词,每个单词首字母大写:HelloWorld,Student
- 变量和方法:首字母小写,如果有多个单词,从第二个单词开始首字母大写:getName, studyJava
- 常量名(自定义常量):所有字母都大写,多个单词用下划线隔开(_):MAX_VALUE
- 包名:全部小写,如果有多级,用点号(.)隔开,遵循域名反写的格式:cn.itcast.demo
必须遵循的原则:
- 驼峰命名:像驼峰那样高低起伏,比如类名和接口名:HelloWorld;方法名:getById;
- 见名知意:看到名字就大概知道它的意思,也就是说标识符的意义要明确、直观,可阅读性强。
类、接口、方法、包等等这些元素我们还没有接触到——除了main方法,但是我很快就会把他们请出来和你见面。它们的命名规范是对你养成良好编码习惯的最基本的要求,无论技术能力上有多强,起码我们的代码风格跟大神们是一样的,这么看来,我们是不是离他们很近了?哈哈哈哈!
简单小结一下,标识符这个知识点需要你:
- 理解标识符的概念
- 熟记标识符的组成部分、定义规则和命名规范,尤其是那两个必须尊徐的原则:驼峰命名、见名知意。
考一考:认识标识符
下面哪些是合法的标识符?
A. aa
B. 0_score
C. public
D. demo3
E. $Outer.Inner
F. ID
答案:ADF
课程总结
定义变量的格式和含义:
数据类型 变量名 = 初始化值;
- 数据类型的分类的用法:
Java 语言中的数据类型,分为两大类:基本数据类型、引用数据类型。
基本类型又分为四类,共八种:
整数型四种:
byte
、short
、int
、long
浮点型两种:
float
、double
字符型一种:
char
布尔型一种:
boolean
整型的默认类型是:
int
;浮点型的默认类型是double
;引用类型包括:类、接口、枚举等类型,我们前面使用过的
String
类型,就是一个普通的类 - 常量相关的知识偏重于理解,所以,对你的要求很简单:
理解常量的概念和分类
能够区分常见的字面值常量
标识符:
组成部分;
定义规则;
命名规范:
- 驼峰命名
- 见名知意
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。