目录
一、标识符
所有可以程序员人为定义的名称都被称为是标识符(除了main【它是java语言开发者定义的】)。比如,类名、方法名、变量名、接口名、常量名......
1.1.标识符的命名
1.1.1.三个命名规则(必须遵守)
1.标识符不能以数字开头,标识符以数字、字母、下划线、$组成
D:\JAVAProgram\test\src\test\CalcTest.java:13:6
java: 需要<标识符>
报错原因:
编译器在检测到class这个单词的时候,就会在class后面的单词中找类名,但是我们所写的类名不符合标识符的命名规则,因此编译器认为它不是一个类名,所以他找不到类名,报错,需要标识符。
2.标识符不能使用java中的关键字
这是因为java中的关键字已经被指定了专门的含义,但是我们如果可以使用关键字来当作类名,那么这个关键字就会拥有了两个含义,我们使用的时候也会不知道使用的是哪个,会很麻烦。
3.java中严格区分大小写
java是一门严格区分大小写的语言,所以,我们也可以通过转换大小写来使用关键字当作类名,但是实际上我们不推荐使用这种方式,因为命个名没有必要给自己找麻烦
1.1.2.两个标准
1.见名知意(看到标识符就知道他的意思)
2.遵守驼峰规则
类、接口:首字母大写,之后每个单词的首字母都大写(大驼峰)
变量、方法:首字母小写,之后每个单词的首字母都大写(小驼峰)
常量名:全部大写,单词之间用_分隔
1.1.3.一个注意事项
java采用的字符集合是unicode编码,因此,严格意义上说,我们可以使用任何国家的任意字符。
1.2.关键字和保留字
所谓的关键字就是java本身已经设定了特定的含义或功能的单词,保留字则是未来有可能称为关键字的单词。
///图片来源于网上百度//
1.3.字符集合
所谓的字符集合,就是人为的规定的一张表,表中将日常使用的字符都对应了一个专门的数字,计算机就是通过保存这个数字来保存和识别我们保存的信息的。
值得注意的是,字符集合表是人为规定的,因此,它有很多个版本。
1.3.1.乱码问题
字符集合有很多个版本,各个版本之间是有可能不兼容的,所以,我们通过使用某一个字符集合在计算机中保存数据的时候,在使用另外一个字符集合编译数据,就会产生乱码问题。
1.3.2.解决办法
1.在使用javac命令的时候,人为的指定专门的编码方式;(较为麻烦)
2.改变DOS或.java文件的自符集合,使两者统一(DOS不能修改,所以我们只能对.java文件的字符集合修改为DOS命令窗口的ANSI即可)
二、字面量
字面量就是我们所谓的数据,主要分为一下五大类:
整数型字面量 1 2 3 10 -100 -20 .......
浮点型字面量 1.3 1.5 3.14 ......
布尔型字面量 true或false(只有这两种)
字符型字面量 'a' 'b' 'c' '中' ......
字符串型字面量 "abc" "ssdasda" "中国" "a" ......
字符型字面量和字符串型字面量都是描述的现实世界中的文字,所有的字符型都是使用单引号括起来的单个字符;所有的字符串型是使用双引号括起来的一个及以上的字符组成的串
在java语法中,我们只需要是用单引号或双引号来区分字符型和字符串型
三、变量
java语言中,只有字面量是远远不够的,这是因为一个字面量的值是定死的,不可改变,因此我们需要一个东西可以参与运算。这就是变量
在程序运行期间,值可以被修改的标识符被称为变量。
变量本质上,是内存当中存储数据的最基本的单元。
三要素:数据类型 变量名 作用域(生命周期、作用范围)
3.1.变量创建
3.1.1.声明变量
语法:数据类型 变量名
//数据类型 变量名
int num;
我们也可以同时声明多个变量,
//创建了三个变量numA,numB,numC,其中numC的值为100
int numA, numB, numC = 100;
3.1.2.初始化变量
语法:变量名 = 字面量
变量的初始化是通过=来进行赋值实现的。
=在java中式赋值的含义,与数学中相等的含义不同。
=号的执行逻辑是从右向左的,下面这句话的含义就是,将字面量21赋值给int类型的num变量
//变量名 = 初始值;
num = 21;
3.1.3.简洁写法
一般的,我们会把声明变量和初始化变量放在一行语句编写。
这句话的含义就是,将字面量21赋值给int类型的变量,变量名为num
//数据类型 变量名 = 初始值;
int num = 21;
3.2.变量使用
创建的变量,需要通过变量名来进行使用(调用)
3.2.1.创建和使用的注意事项
1.变量声明的时候一定要确定变量的数据类型(强类型语言)
//数据类型 变量名
int num;
2.变量在使用之前需要保证初始化(赋初始值)
//变量名 = 初始值;
//num = 21;
System.out.println("num");//报错,因为没有初始化(局部变量)
3.变量在程序运行期间,值可以发生改变(可以重新赋值,但不能重新声明)
//变量名 = 初始值;
num = 21;
4.变量的声明和赋值一般情况下会写到一起
//数据类型 变量名 = 初始值;
int num = 21;
5.与数据类型无关,跟作用域有关,同一作用域中,变量名不能重复
3.3.变量的分类
在方法体中声明的变量称为局部变量
在方法体之外声明的变量称为成员变量
3.2.1.区别
局部变量只在方法体当中有效,方法体执行结束,该变量的内存就被释放了
局部变量的变量名和成员变量的变量名可以重复
当在一个方法体中使用某个变量的时候,会先在方法体中寻找,找不到就回去成员变量中寻找。
3.4.变量的作用域
我们所创建的变量,都只在本身被创建的这个大括号中该行语句的下面才有用。
出了大括号,变量就没有意义了。也就是说,我们在这个变量所在的大括号的外面使用改变量是不可行的,或报错,未定义。
四、常量
所谓的常量正好跟变量相反,常量即使不可改变的值,在java中相同的常量只有一个。假设,如果我们有两个string类型数据,值都是“hello”。虽然他们所指向的引用地址不同,但是他们的地址实际上都指向的是常量池中的“hello”。
五、数据类型
java是一门强类型的语言,所有的变量和值都具备类型,他把数据类型分为基本数据类型和引用数据类型两种。
Java语言会根据不同的数据类型分配不同的内存空间
基本数据类型
基本数据类型分为三大类八小种/四类八种
三大类
数值型
整数型
byte、short、int、long
浮点型
float、double
字符型
char
逻辑型
boolean
引用数据类型
类
数组
接口
5.1.基本数据类型
5.1.1.数值类型
5.1.1.1.整数型
字节型byte(1字节)
表示范围:[-128,127]
//1.声明一个byte类型的变量
byte 变量名;
byte b;
//2.给该变量进行赋值,注意数据类型的取值范围
b = 10;
//也可以在声明的时候直接赋值
byte b = 10;
注意事项:
1.给byte型变量赋值的时候不能超过对应的取值范围
2.超过取值范围的时候会报错: 不兼容的类型:从int类型转换到byte可能会有丢失
D:\JAVAProgram\test\src\test\ByteTest.java:6:13
java: 不兼容的类型: 从int转换到byte可能会有损失
短整型short(2个字节)
表示范围:[-32768,32767]
//1.声明一个short类型的变量
short 变量名;
short s;
//2.给该变量进行赋值,注意数据类型的取值范围
s = 10;
//也可以在声明的时候直接赋值
short s = 10;
注意事项:
1.给short型变量赋值的时候不能超过对应的取值范围
2.超过取值范围的时候会报错: 不兼容的类型:从int类型转换到short可能会有丢失
D:\JAVAProgram\test\src\test\ShortTest.java:6:13
java: 不兼容的类型: 从int转换到short可能会有损失
整型int(4个字节)
表示范围:[-2147483648,2147482647]
//1.声明一个int类型的变量
int 变量名;
int i;
//2.给该变量进行赋值,注意数据类型的取值范围
i = 10;
//也可以在声明的时候直接赋值
int i = 10;
注意事项:
1.给short型变量赋值的时候不能超过对应的取值范围
2.超过取值范围的时候会报错: 整数太大
D:\JAVAProgram\test\src\test\IntTest.java:6:13
java: 整数太大
长整型long(8个字节)
表示范围:很大很大
//1.声明一个long类型的变量
long 变量名L/l;
long i;
//2.给该变量进行赋值,注意数据类型的取值范围
i = 10L;
i = 10l;
//也可以在声明的时候直接赋值
long i = 10L;
注意事项:
1.给short型变量赋值的时候不能超过对应的取值范围
2.超过取值范围的时候会报错: 整数太大
D:\JAVAProgram\test\src\test\LongTest.java:5:18
java: 整数太大
原因:
1.在java中所有的整数字面值默认类型是int类型,当将一个超过了int类型范围的整数字面量赋值给long类型变量的时候,需要在字面值后面加小写 l 或者是大写 L
整数赋值方式
二进制:jdk1.7之后支持二进制的赋值方式,以0b/0B开头
byte i = 0b10;
八进制:赋值方式以0开头
byte i = 010;
十进制:赋值方式中可以通过_分割数值
byte i = 10_20;
十六进制:赋值方式以0x开头
byte i = 0x10;
5.1.1.2.浮点型
双精度double(8个字节)
精确值:14-16位
当我们对精度的要求较高的时候,就不要使用double类型,使用BigDecimal
//1.声明一个double类型的变量
double 变量名;
double i;
//2.给该变量进行赋值,注意数据类型的取值范围
i = 10;
//也可以在声明的时候直接赋值
double i = 10;
单精度float(4个字节)
精确值:6-7位
//1.声明一个float类型的变量
float 变量名F/f;
float i;
//2.给该变量进行赋值,注意数据类型的取值范围
i = 10f;
i = 10F;
//也可以在声明的时候直接赋值
float i = 10F;
注意:
1.在java中所有的浮点数默认值类型都是double类型,当将一个小数赋值给float类型变量的时候,需要在字面值后面加小写 f 或者是大写的 F
2.不要使用浮点数来进行四则运算,统一扩大倍数之后,可以使用BigDecimal完成浮点数的运算
3.计算机不能精确的表示浮点数的运算,我们可以通过适当的扩大倍数或缩小倍数来实现。
浮点型赋值方式
方式一:普通赋值
double d = 2.0;
方式二:省略0,当我们的浮点数是0.xxxxxxx的时候,我们可以省略0
double d = .5;
方式三:科学计数法
double d = 1.5E-5;//0.000015
5.2.字符型
5.2.1.char类型(2字节)
表述范围:[0,65535]
字符型数据,采用单引号包起来的单个字符,零个或多个字符都是是不可以的。
声明变量
//声明char类型变量
char 变量名;
//赋值
变量名 = '字符';
//声明并赋值
char 变量名 = '字符';
赋值方式一 直接通过单引号在声明的时候同时进行赋值
char cj = 'a';
赋值方式二 通过一个int类型的数据在声明一个char类型数据的时候同时进行赋值
当我们使用int类型数据来给chart类型数据赋值声明的时候,我们需要注意不能给一个负值,这是因为在ASCLL编码表中,代表字符的Number中最小的就是0,所以会报错;
本质上是,int类型的数据占用4个字节,char类型的数据占用了2字节。因此,int类型变量的的取值范围要比char类型的取值范围要大,虽然,我们可以通过ASCLL编码表中的数字来给char类型赋值声明,但是,如果我们使用的int类型数据超出了这个表的范围,那么就会造成数据的缺失,因此报错。
char cj = 65;
赋值方式三 通过字符集或unicode代码点来在声明char类型数据的时候同时进行赋值
unicode实际上是一个类似ASCLL编码表的一个表,但是这个表是unicode给出的。也就是规范不同。
在unicode中,是通过16进制的数字来表示不同的字符的,ASCLL表则是10进制的数字。
当我们使用unicode编码点来进行赋值声明的时候,电脑首先默认的数字是通过ASCLLL表来进行结束,因此,我们首先需要通过\u来告诉我们的电脑,我们后面的四位数字,是需要对照unicode表中来进行解释的,然后,在后面跟上我们想要表示的字符的unicode表对应的16进制数字。
char cj = '\u0000';
5.3.逻辑类
5.3.1.boolean类型(1个字节)
实际占用存储空间是1位,一字节的八分之一。
声明方式
//声明一个布尔类型变量
boolean 变量名;
赋值
true false
//给布尔类型变量赋值
变量名 = true;
变量名 = false;
六、引用数据类型
除了基本数据类型以外的其他数据类型都是引用数据类型。
6.1.类class
6.2.数组array
6.3.接口interface
七、转义字符
转换含义-----本质上,将眼睛所看到的含义转换成另外一个含义。
7.1.为什么要使用转义字符?
在我们的编程过程中,我们可能需要输出一些特殊字符,比如,单引号、双引号等,我们以单引号举例;在编程中,我们的单引号实际上指的是一个char类型数据,不是我们普遍意义上的单引号,这个时候我们就需要使用转义字符来讲本身char类型数据的含义转义成我们普通的单引号。
7.2.常用的转义
\' 一个单引号
char cj = '\'';
\n 换行
本质上就是把光标移动到下一行的开头
char cj = '\n';
\t 制表符
每个制表符代表的是八个字符,不满八个字符的使用空格代替。
注意:我们使用的制表符判断的是制表符前面的字符,而不是后面的。
char cj = '\t';
\r 将图标移动到本行开头
也就是说,即使我们前面输出了一些字符,但是遇到这个\r的时候,光标就会自动移动到本行开头,我们后面的输出就会把前面的输出覆盖掉。
char cj = '\r';
\r\n 等同于window中的回车
char cj = '\r\n';
八、运算符
运算符是让我们可以对保存的数据进行运算的符号,并将运算结果返回。也就是说,我们可以通过运算符来对我们的数据进行运算操作。
我们的运算符本身只是一个符号,代表了某种运算规则,参与运算的数叫做操作数,操作数有时也可以是一个表达式,只要表达式进行运算的结果的数据类型符合该操作符对于数据类型的要求即可。
操作数、运算符两者共同组成表达式。
对于运算符而言,操作数为字面量的时候,表达式的值就是一个字面量,此时赋值符号的运算结果就和直接初始化一致;当时当操作数不是字面量,而是包含了变量的时候,此时赋值符号的运算结果就与右边的操作数是一个隐式抓换数据类型后的最大数据类型的情况下所得结果一致。
8.1.算数运算符
顾名思义,就是进行算术运算的符号,但是实际上,我们的算术运算符在除了一些基本的算术运算的功能外,还会有一些其他的额外用法。
操作数的类型一般是数字类型,我们也可以使用单个字符串来进行运算。
操作数为char类型
当我们算术运算符的操作数中含有char类型数据字符的时候,他会根据ASCLL表把char类型的字符数据转换成对应的数字之后在进行算术运算。
char i = 'a';
float j = i + i;//194.0
float j = i - i;//0.0
float j = i * i;//9409.0
float j = i / i;//1.0
float j = i % i;//0.0
运算规则:同等级的运算,从前往后,依次执行。每次把当前运算的运算结果当做下一次运算的一个操作数。
8.1.1.+
操作数
数字、单个字符、字符串、
作用
1.作为数字正负号中的正号使用
我们数学中的数字是有正有负的,和数学一样,我们可以通过这个运算符来代表我们数字的正号。
2.进行普通的加法运算
将我们的运算符两边的操作数进行加法运算,将运算结果返回。
3.作为拼接符使用
当我们算术运算符两边的操作数中含有一个字符串的时候,这个时候的加法运算符就是作为一个拼接符来使用的,他会把加号两边的操作数拼接成一个新字符串作为运算结果。
8.1.2.-
操作数
数字、单个字符
作用
将我们的运算符两边的操作数进行减法运算,将运算结果返回。
8.1.3.*
操作数
数字、单个字符
作用
将我们的运算符两边的操作数进行乘法运算,将运算结果返回。
8.1.4./
操作数
数字、单个字符
作用
将我们的运算符两边的操作数进行除法运算,将运算结果返回。
8.1.5.%
操作数
数字、单个字符
作用
将我们的运算符两边的操作数进行取模运算,将运算结果返回。
8.2.一元运算符
一元运算符有很多,这里我们对自增和自减来进行解释。
8.2.1.++
自增运算符
自增是变量在自身的基础上加1
++i
先将i的值+1,再用加1后的值进行当前运算。
i++
先用本来的a进行当前运算。运算结束后,将i的值+1
8.2.2.--
自减运算符
自减是变量在自身的基础上减1
--i
先将i的值-1,再用减1后的值进行当前运算。
i--
先用本来的a进行当前运算。运算结束后,将i的值-1
8.3.赋值运算符
8.3.1.=
赋值运算符就是我们的赋值操作所需要使用的运算符。自右向左进行运算。
8.4.扩展运算符
算术运算符+赋值运算符 位运算符+赋值运算符
优点:
提升编译效率
提升开发效率
缺点:
不利于阅读,可读性差
注意:
1.该运算符会自动进行类型转换,将类型传换成运算符右边的数据类型。因此,我们需要在确定类型转换后不会数据丢失导致运行结果错误时才能使用。
8.4.1.+=
相当于将符号左边的操作数和符号右边的操作数进行加法运算,并将结果赋值给左边的操作数。
8.4.2.-=
相当于将符号左边的操作数和符号右边的操作数进行减法运算,并将结果赋值给左边的操作数。
8.4.3.*=
相当于将符号左边的操作数和符号右边的操作数进行乘法运算,并将结果赋值给左边的操作数。
8.4.4./=
相当于将符号左边的操作数和符号右边的操作数进行除法运算,并将结果赋值给左边的操作数。
8.4.5.%=
相当于将符号左边的操作数和符号右边的操作数进行取模运算,并将结果赋值给左边的操作数。
8.5.关系运算符
关系运算符的结果是一个布尔类型的值,< 、<=、>=只能对基本数据类型进行比较,==、!=则是基本数据类型和引用数据类型都可以比较。
8.5.1.<
对运算符左右两边的操作数进行比较,当满足左操作数小于右操作数时,返回值为true;否则返回false。
8.5.2.<=
对运算符左右两边的操作数进行比较,当满足左操作数小于或等于右操作数时,返回值为true;否则返回false。
8.5.3.>
对运算符左右两边的操作数进行比较,当满足左操作数大于右操作数时,返回值为true;否则返回false。
8.5.4.>=
对运算符左右两边的操作数进行比较,当满足左操作大于或等于右操作数时,返回值为true;否则返回false。
8.5.5.==
对运算符左右两边的操作数进行比较,当满足左操作数等于右操作数时,返回值为true;否则返回false。
8.5.6.!=
对运算符左右两边的操作数进行比较,当满足左操作数不等于右操作数时,返回值为true;否则返回false。
8.5.7.instanceof
引用 instance 类型
作用:
判断前面的引用是否为后面类型的对象
8.6.逻辑运算符
逻辑运算符两边的操作数都是bollean类型。值得注意的是,我们的&以及|两个运算符不仅仅是逻辑运算符,还是位运算符。所以,只有符号两边的操作数都是boolean类型的值时,我们中间的运算符才是逻辑运算符,其他情况时,该运算符为位运算符。
8.6.1.逻辑与&
当我们使用逻辑与来进行运算的时候,我们会将运算符左右操作数的值全部算出来,再根据该值来得到最后的结果。
8.6.2.短路与&&
当我们使用短路与来进行运算的时候,如果运算符左操作数的值已经是false的时候,整个运算的结果就是false了,直接返回结果,不会再去判断右操作数的值。
8.6.3.逻辑或|
当我们使用逻辑或来进行运算的时候,我们会将运算符左右操作数的值全部算出来,再根据该值来得到最后的结果。
8.6.4.短路或||
当我们使用短路或来进行运算的时候,如果运算符左操作数的值已经是true的时候,整个运算的结果就是true了,直接返回结果,不会再去判断右操作数的值。
8.6.5.逻辑非!
逻辑非运算符是一个单目运算符,也就是说它只需要一个操作数,该操作数需要跟在运算符的后面。true转换成false;false转换成true。
8.6.6.异或^
当我们使用异或来进行运算的时候,如果运算符左操作数和右操作数的值相同,都为true或都为false的时候,整个运算的结果就是false;否则,运算式的结果位true。
8.7.三目运算符
所谓的三目运算符从名字来看,就是需要三个操作数。
8.7.1.基础语法
操作数1 ? "操作数2" : "操作数3"
8.7.2.执行流程
1.首先,我们需要判断操作数1的值,当值位true,进入操作2;值为false,进入操作3;
2.计算操作数2的值,该值就是这条三目运算符表达式最后的计算结果
3.计算操作数3的值,该值就是这条三目运算符表达式最后的计算结果
8.8.位运算符
位运算符是针对于二进制来进行运算的,也就是说,我们的位运算两边的操作数,看上去我们写的是数字,但是实际上,进行运算的是两者的二进制码来进行运算,所以,位运算的执行效率更高。
1表示true;0表示false
8.8.1.位与&
当使用位与运算符进行运算的时候,我们运算符两边的操作数对应的二进制数会逐位进行位与运算,两者只要有一个0的时候,该位的运算结果就是0
8.8.2.位或|
当使用位或运算符进行运算的时候,我们运算符两边的操作数对应的二进制数会逐位进行位或运算,两者只要有一个1的时候,该位的运算结果就是1.
8.8.3.位非~
位非运算符和逻辑非运算符都是单目运算符,因此只需要一个操作数跟在运算符的后面即可。
当我们使用位非运算符的时候,我们是将操作数对应的二进制数逐位进行取反操作,包括符号位,即0变成1;1变成0。
8.8.4.位异或^
当使用位异或运算符进行运算的时候,我们运算符两边的操作数对应的二进制数会逐位进行位异或运算,两者只要有不同的时候,该位的运算结果就是1;相同,该位的运算结果就是0。
注意
1.当一个数对其本身进行位异或操作时,得到的结果是0。
2.当一个数和0进行位异或操作时,得到的结果是他本身。
我们可以通过这两个特点,来不使用新变量来将两个变量的值呼唤,只需要通过三次位异或运算即可。
int num1 = 111;
int num2 = 222;
num1 = num1 ^ num2;
num2 = num1 ^ num2;
num1 = num1 ^ num2;
8.8.5.位左移<<
位左移是把左操作数对应的二进制数前面去除掉一定的位数,并在后面通过0来补足需要的位数。这个位数由我们的右操作数来指定。
8.8.6.位右移>>
位右移是把左操作数对应的二进制数后面去除掉一定的位数,并在前面通过符号位来补足需要的位数。这个位数由我们的右操作数来指定。
8.8.7.无符号数右移>>>
无符号数需要的操作数跟有符号数是相同的,他在对正数的操作上和位右移是一样的,使用0来补齐,但是在对负数进行操作的时候,他会在前面通过0补足,而不是负数的符号位。
8.9.运算符的优先级
网上图片,取自语言中文网//
8.9.1.遇事不决加括号()
当我们在编程中,遇到我们无法判断优先级是否符合自己的要求的时候,我们可以通过加上括号来人为的控制程序代码段的执行顺序。
8.9.2.算数》关系》逻辑》三目》赋值
事实上,理解起来是很容易的,我们的数字需要进行运算,因此算数运算符优先级最高;运算结果可以是boolean类型,也可是其他类型,所以,关系运算符排在算数运算符的后面;当运算结果是boolean类型的时候,我们可以通过逻辑运算符来进行程序的控制,因此,第三位是逻辑运算符;三目运算符既可以当作逻辑运算符来使用,其也有结果,需要呗赋值,因此可以放在赋值运算符的前面即可;赋值往往是一行代码中最后执行的,因此,最后的是赋值。
8.9.3.单目》双目》三目
8.10.数据类型转换
当我们给byte,short、char赋值的时候,可以通过int型字面量进行赋值,只要不超过范围即可,但是通过变量赋值就直接报错了。
8.10.1.自动类型转换(小转大)
当我们将小范围的数据类型进行了算术运算或是需要赋值给大范围的数据类型的时候,也就是说,等号的右边是一个小范围的数据类型,等号的左边是一个大范围的数据类型,因此需要进行数据类型的转换,java会帮我们做这个自动的类型转换。
转换规则
byte》short》int》long》float》double
char 》int
注意
char 和 short虽然都是同大小的数据,但是不能自动转换。
8.10.2.强制类型转换(大转小)
当我们将大范围的数据类型赋值给小范围的数据类型的时候,我们就需要使用强制类型转换来帮我们达成这件事情。但是需要注意的是,我们需要在保证数据是包含在小范围数据类型的范围中的,否则就会导致我们转换后的数据发生错误。
int i = 100;
byte j;
j = (byte) i;//不会发生数据错误,byte的数据范围是-128-127
i = 128;
j = (byte) i;//发生数据错误,此时j的值是-128