1 Java 规范
1.1 注释
优秀的代码就是最好的注释,但有多少人可以达到这一步呢?养成写注释的好习惯吧!
// 单行注释
/*
* 多行注释
*/
/** 文档注释
* @Description Hello Word
* @Author Nick
*/
1.2 标识符
- 标识符必须以字母、下划线(_)、数字或美元($)组成;
- 标识符必须由字母、下划线(_)或美元($)开头,不能由数字开头;
- 标识符不能是关键字或者保留字;
- 标识符中不能有空格;
- 标识符没有长度限制;
- 标识符对大小写敏感。
标识符的使用规范
- 表示类名的标识符:每个单词的首字母大写,如Book, JavaBook
- 表示方法和变量的标识符:第一个单词小写,从第二个单词开始首字母大写,我们称之为“驼峰原则”,如read(), readBook()
- 表示常量的标识符:全部单词大写,用下划线分隔
1.3 关键字&保留字
- 关键字是对Java的编译器有特殊的意义,他们用来表示一种数据类型,或者表示程序的结构等;
- 保留字是为Java预留的关键字,虽然现在没有作为关键字,但在以后的升级版本中有可能作为关键字;
下表是Java中的关键字和保留字:
abstract | continue | goto | null | switch |
---|---|---|---|---|
assert | default | if | package | synchronized |
boolean | do | implements | private | this |
break | double | import | protected | throw |
byte | else | instanceof | public | throws |
case | extends | int | return | transient |
catch | final | interface | short | try |
char | finally | long | static | void |
class | float | native | strictfp | volatile |
const | for | new | super | while |
2 数据类型
2.1 数据类型概述
几乎所有的编程语言中都会有数据类型,什么是数据类型呢?软件的存在主要是进行数据的处理,现实生活中的数据会有很多,所以编程语言对其进行了分门别类,然后不同的数据类型的数据会给其分配不同大小的空间进行存储。换句话说,java中的数据类型作用就是指导java虚拟机在程序运行阶段到底应该给该变量分配多大的内存空间。
2.2 数据类型分类
Java中的数据类型包括两种:
- 基本数据类型
- 引用数据类型
Java中的基本数据类型又包括四类8种:
- 整数型(不带小数的数字):byte, short ,int, long
- 浮点型(带小数的数字):float, double
- 字符型(文字,单个字符):char
- 布尔型(真和假):boolean
java中除了以上的8种基本数据类型之外,其它的数据类型均属于引用数据类型,也就是说字符串在java中不属于基本数据类型,而属于引用数据类型。
八种基本数据类型对照表:
数据类型 | 占用bit位 | 取值范围 | 缺省默认值 |
---|---|---|---|
byte(字节型) | 1 | [-128~127] | 0 |
short(短整型) | 2 | [-32768~32767] | 0 |
int(整型) | 4 | [-2147483648~2147483647] | 0 |
long(长整型) | 8 | 0L | |
float(单精度) | 4 | 0.0f | |
double(双精度) | 8 | 0.0 | |
boolean(布尔型) | 1 | true、false | false |
char(字符型) | 2 | [0~65535] | ‘\u0000’ |
3 变量&常量
3.1 变量本质
变量就是代表一个“可操作的存储空间”,空间位置是确定的,但是里面放置什么值不确定。我们可通过变量名来访问“对应的存储空间”,从而操纵这个“存储空间”存储的值。
Java是一种强类型语言,每个变量都必须声明其数据类型。变量的数据类型决定了变量占据存储空间的大小。 比如,int a = 3; 表示a变量的空间大小为4个字节,不同数据类型存储空间的大小请看上表。
3.2 变量的声明
变量在使用前必须对其声明, 只有在变量声明以后,才能为其分配相应长度的存储空间。
变量作为程序中最基本的存储单元,其要素包括变量名,变量类型和作用域。
/**
* 格式:
* 数据类型 变量名 [=初始值] [,变量名 [=初始值]…];
* type varName [=value][,varName[=value]...];
* []中的内容为可选项,即可有可无
*/
// 示例
double salary;
long id= 2L;
int width = 18, length = 20;
注意事项
- 每个变量都有类型,类型可以是基本类型,也可以是引用类型。
- 变量名必须是合法的标识符
- 变量声明是一条完整的语句,因此每一个声明都必须以分号结束
3.3 变量的分类
变量根据声明的位置不同可以分为:
- 局部变量
- 成员变量
- 静态成员变量(类变量)
- 实例成员变量(实例变量)
在方法体当中声明的变量以及方法的每一个参数变量都是局部变量。
在方法体外,类体内声明的变量称为成员变量。
- 成员变量声明时如果使用static关键字修饰的称为静态成员变量(简称静态变量或类变量)
- 如果没有static关键字修饰则称为实例成员变量(简称实例变量)
如以下代码:
public class VarDemo{
// 成员变量(实例变量)
int x = 20;
// 静态成员变量(类变量)
static int y = 200;
// 方法:int a, int b 都是局部变量
public int sum(int a, int b){
// 局部变量
int sum = a + b;
return sum;
}
}
3.4 变量的作用域
- 局部变量
方法或语句块内部定义的变量。
生命周期是从声明位置开始到到方法或语句块执行完毕为止。
方法体当中的代码是有执行顺序的,遵循自上而下的顺序依次逐行执行,所以局部变量在没有声明的时候是不能访问的,需要先声明,再使用。
- 实例变量
方法外部、类的内部定义的变量。从属于对象,生命周期伴随对象始终。如果不自行初始化,它会自动初始化成该类型的默认初始值。
- 类变量
使用static定义。 从属于类,生命周期伴随类始终,从类加载到卸载。如果不自行初始化,与成员变量相同会自动初始化成该类型的默认初始值
3.5 变量归纳一览表:
局部变量、成员变量、静态变量的区别 | |||
---|---|---|---|
类型 | 声明位置 | 从属于 | 生命周期 |
局部变量 | 方法或语句块内部 | 方法/语句块 | 从声明位置开始,直到方法或语句块执行完毕,局部变量消失 |
成员变量 (实例变量) |
类内部,方法外部 | 对象 | 对象创建,成员变量也跟着创建。对象消失,成员变量也跟着消失; |
静态变量 (类变量) |
类内部,static修饰 | 类 | 类被加载,静态变量就有效;类被卸载,静态变量消失。 |
3.7 常量
常量通常指的是一个固定的值,例如:1、 2、 3、 ‘a’、 ‘b’、 true、 false、 “helloWorld” 等。
在Java语言中,主要是利用关键字 final 修饰变量来定义一个常量。
常量一旦被初始化后不能再更改其值。
4 运算符
4.1 算术运算符
算术运算是一种常见的运算,主要是对数值型数据进行加减乘除等运算
运算符 | 名称 | 备注 |
---|---|---|
+ | 加运算符 | 两数相加 |
- | 减运算符 | 两数相减 |
* | 乘运算符 | 两数相乘 |
/ | 除运算符 | 两数相乘,若是两个整数相除,只保留整数部分 |
% | 取模(取余)运算符 | 被除数为正数结果都为正,被除数为负数结果都为负 |
++ | 自增 | ++变量名:变量在参与其他操作前先将自己加1 变量名++:先用原来的值参与其他操作后,再将自己加1 |
— | 自减 | —变量名:变量在参与其他操作前先将自己减1 变量名—:先用原来的值参与其他操作后,再将自己减1 |
+ | 字符串连接 | 当操作数中只要有一个是String类型,系统会自动将另一个操作数转换成字符串类型,然后进行连接 |
4.2 赋值运算符
| 运算符
| 名称
| 例子
| 说明
| | —- | —- | —- | —- | | =
| 赋值运算符
| i = 6
| 6赋值给i
| | +=
| 加简捷赋值运算符
| i += 6
| 同i =i + 6
| | -=
| 减简捷赋值运算符
| i -= 6
| 同i = i - 6
| | *=
| 乘简捷赋值运算符
| i *= 6
| 同i = i * 6
| | /=
| 除简捷赋值运算符
| i /= 6
| 同i = i / 6
| | %=
| 取模简捷赋值运算符
| i %= 6
| 同i = i % 6
|
4.3 关系运算符
运算符 | 名称 | 样例 | 结果说明 |
---|---|---|---|
> | 大于 | 1 > 2 | false |
>= | 大于等于 | 1 >= 2 | false |
< | 小于 | 1 < 2 | true |
<= | 小于等于 | 1 <= 2 | true |
== | 等于 | 1 == 2 | false |
!= | 不等于 | 1 != 2 | true |
4.4 逻辑运算符和表达式
运算符 | 名称 | 运算规则 | |
---|---|---|---|
&& | 与运算符 | 短路与 | 运算符左右两端的操作数只要有一个为false,直接返回false |
| | | 或运算符 | 短路或 | 运算符左右两端的操作数只要有一个为true,直接返回true |
! | 非运算符 | 逻辑取反 | 操作数为true,结果为false;操作数为false,结果为true |
| | 或运算符 | 逻辑或 | 运算符左右两端的操作数都为false,表达式结果才为false,其它情况表达式结果为true |
& | 与运算符 | 逻辑与 | 运算符左右两端的操作数都为true,表达式结果才为true,其它情况表达式结果为false |
^ | 异或运算符 | 逻辑异或 | 操作数相同为false,不同为true |
4.5 位运算符
操作符 | 描述 | 例子 |
---|---|---|
& | 如果相对应位都是1,则结果为1,否则为0 | (A&B),得到12,即0000 1100 |
| | 如果相对应位都是 0,则结果为 0,否则为 1 | (A | B)得到61,即 0011 1101 |
^ | 如果相对应位值相同,则结果为0,否则为1 | (A ^ B)得到49,即 0011 0001 |
〜 | 按位取反运算符翻转操作数的每一位,即0变成1,1变成0。 | (〜A)得到-61,即1100 0011 |
<< | 按位左移运算符。左操作数按位左移右操作数指定的位数。 | A << 2得到240,即 1111 0000 |
>> | 按位右移运算符。左操作数按位右移右操作数指定的位数。 | A >> 2得到15即 1111 |
>>> | 按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充。 | A>>>2得到15即0000 1111 |
4.6 三目条件运算符
三目条件运算符的语法为:布尔表达式 ? 表达式1 : 表达式2
计算结果: 布尔表达式 为 true, 计算结果为表达式1,否则为表达式2
4.7 表达式
表达式是符合一定语法规则的运算符和运算数的序列。按照使用的运算符和运算结果的不同可以分为:
- 算术表达式
例如:(x + y - 1) * 10
- 关系表达式
例如:x > y, x >= y, x != y, x == y
- 逻辑表达式
例如:x && y, x || y || z, (!x) && (!y)
- 赋值表达式
例如:x=y, x+=y
关于表达式,有下面几个概念需要介绍。
- 表达式的值:对表达式中操作数进行运算得到的结果称为表达式的值;
- 表达式的类型:表达式值的数据类型即为表达式的类型;
- 表达式的运算顺序:应按照运算符的优先级从高到低的顺序进行,优先级相同的运算符按照事先约定的结合方向
4.8 运算符优先级
| 优先级 | 运算符 | 类 | 结合性 | | —- | —- | —- | —- | | 1 | () | 括号运算符 | 由左至右 | | 2 | !、+(正号)、-(负号) | 一元运算符 | 由左至右 | | 2 | ~ | 位逻辑运算符 | 由右至左 | | 2 | ++、— | 递增与递减运算符 | 由右至左 | | 3 | 、/、% | 算术运算符 | 由左至右 | | 4 | +、- | 算术运算符 | 由左至右 | | 5 | <<、>> | 位左移、右移运算符 | 由左至右 | | 6 | >、>=、<、<= | 关系运算符 | 由左至右 | | 7 | ==、!= | 关系运算符 | 由左至右 | | 8 | & | 位运算符、逻辑运算符 | 由左至右 | | 9 | ^ | 位运算符、逻辑运算符 | 由左至右 | | 10 | | | 位运算符、逻辑运算符 | 由左至右 | | 11 | && | 逻辑运算符 | 由左至右 | | 12 | || | 逻辑运算符 | 由左至右 | | 13 | ? : | 条件运算符 | 由右至左 | | 14 | =、+=、-=、=、/=、%= | 赋值运算符、扩展运算符 | 由右至左 |
5 修饰符
Java语言提供了很多修饰符,主要分为以下两类:
- 访问修饰符
- 非访问修饰符
5.1 访问控制修饰符
Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java 支持 4 种不同的访问权限。
- default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
- private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
- public : 对所有类可见。使用对象:类、接口、变量、方法
- protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
我们可以通过以下表来说明访问权限:
修饰符 | 当前类 | 同一包内 | 子孙类(同一包) | 子孙类(不同包) | 其他包 |
---|---|---|---|---|---|
public | Y | Y | Y | Y | Y |
protected | Y | Y | Y | Y/N | N |
default | Y | Y | Y | N | N |
private | Y | N | N | N | N |
1. public - 公有访问修饰符
被声明为 public 的类、方法、构造方法和接口能够被任何其他类访问。
如果几个相互访问的 public 类分布在不同的包中,则需要导入相应 public 类所在的包。由于类的继承性,类所有的公有方法和变量都能被其子类继承。
2. protected - 受保护的访问修饰符
protected 需要从以下两个点来分析说明:
- 子类与基类在同一包中:被声明为 protected 的变量、方法和构造器能被同一个包中的任何其他类访问;
- 子类与基类不在同一包中:那么在子类中,子类实例可以访问其从基类继承而来的 protected 方法,而不能访问基类实例的protected方法。
protected 可以修饰数据成员,构造方法,方法成员,不能修饰类(内部类除外)。
接口及接口的成员变量和成员方法不能声明为 protected。
子类能访问 protected 修饰符声明的方法和变量,这样就能保护不相关的类使用这些方法和变量。
如果我们只想让该方法对其所在类的子类可见,则将该方法声明为 protected。
3. default - 默认访问修饰符-不使用任何关键字
使用默认访问修饰符声明的变量和方法,对同一个包内的类是可见的。
接口里的变量都隐式声明为 public static final,而接口里的方法默认情况下访问权限为 public。
4. private - 私有访问修饰符
私有访问修饰符是最严格的访问级别,所以被声明为 private 的方法、变量和构造方法只能被所属类访问,并且类和接口不能声明为 private。
private 访问修饰符的使用主要用来隐藏类的实现细节和保护类的数据。
5.2 访问控制和继承
请注意以下方法继承的规则:
- 父类中声明为 public 的方法在子类中也必须为 public。
- 父类中声明为 protected 的方法在子类中要么声明为 protected,要么声明为 public,不能声明为 private。
- 父类中声明为 private 的方法,不能够被子类继承。
5.3 非访问修饰符
为了实现一些其他的功能,Java 也提供了许多非访问修饰符。
static 修饰符,用来修饰类方法和类变量。
final 修饰符,用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
abstract 修饰符,用来创建抽象类和抽象方法。
synchronized 和 volatile 修饰符,主要用于线程的编程。
1. static 修饰符
- 静态变量:static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。 静态变量也被称为类变量。局部变量不能被声明为 static 变量。
- 静态方法:static 关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据,然后计算这些数据。
对类变量和方法的访问可以直接使用 classname.variablename 和 classname.methodname 的方式访问。
2. final 修饰符
final 变量:
final 表示”最后的、最终的”含义,变量一旦赋值后,不能被重新赋值。被 final 修饰的实例变量必须显式指定初始值。
final 修饰符通常和 static 修饰符一起使用来创建类常量。
final 方法:
父类中的 final 方法可以被子类继承,但是不能被子类重写。
声明 final 方法的主要目的是防止该方法的内容被修改。
final 类:
final 类不能被继承,没有类能够继承 final 类的任何特性。
3. abstract 修饰符
抽象类:
抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。
一个类不能同时被 abstract 和 final 修饰。如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误。
抽象类可以包含抽象方法和非抽象方法。
抽象方法
抽象方法是一种没有任何实现的方法,该方法的具体实现由子类提供。
抽象方法不能被声明成 final 和 static。
任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。
如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类可以不包含抽象方法。
抽象方法的声明以分号结尾。
4. synchronized 修饰符
synchronized 关键字声明的方法同一时间只能被一个线程访问。
synchronized 修饰符可以应用于四个访问修饰符。
5. transient 修饰符
序列化的对象包含被 transient 修饰的实例变量时,java 虚拟机(JVM)跳过该特定的变量。
该修饰符包含在定义变量的语句中,用来预处理类和变量的数据类型。
6. volatile 修饰符
volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
一个 volatile 对象引用可能是 null。