Java 基础
编码规范
命名规范
命名方法
- 匈牙利命名
- 一般值命名变量
- 原则:变量名=类型前缀+描述
- 例如:bFoo(布尔型变量)、pFoo(指针类型变量)
- 驼峰命名(最常用)
- 混合使用大小写字母命名
- 小驼峰法:第一个单词小写,其他单词首字母大写,例如:myRoomCount
- 大驼峰法:单词首字母都大写,例如:ClassRoom
- 匈牙利命名
包名:全小写,中间可以用点(.)分隔开,
- 作为命名空间,报名应具有唯一性,可以采用公司或组织域名倒置
- java 核心库报名不采用域名倒置,例如:java.awt.event
类和接口名:采用大驼峰法
文件名:大驼峰法
变量:小驼峰法
常量名:全大写,由多个单词组成的用下划线(_)分隔开,例如:YEAR、WEEK_OF_MONTH
方法名:小驼峰法
注释规范
- 单行注释(//)
- 多行注释(/* … */)
- 文档注释(/** … */)
文件注释
在每一个文件开头添加注释
通常包含版权信息、文件名、所在模块、作者信息、历史版本信息、文件内容、作用
1 | /* |
文档注释
能生成 API 帮助文档
JDK 中 javadoc 命令能提取这些注释信息并生成 HTML 文件
文档注释主要对类(或接口)、实例变量、静态变量、实例方法、静态方法进行注释
文档注释标签
标签 功能 @author 说明类或接口的作者 @deprecated 说明类、接口或成员已经废弃 @param 说明方法参数 @return 说明返回值 @see 参考另一个主题的链接 @exception 说明方法所抛出的异常类 @throws 同@exception @version 类或接口版本 生成 API 帮助文档,可以使用 javadoc 命令
代码注释
- 单行://
- 多行:/* … */
地标注释
// TODO
:此处由待处理任务,或未完成的代码// FIXME
:此处代码是错误的,需要修正// XXX
:此处代码已经完成,但是实现的方法还有待商讨
排版
空行
- 类声明和接口之间保留两个空行
- 两个方法之间保留一个空行
- 方法的第一条语句之前保留一个空行
- 代码注释(尾端注释除外)之前保留一个空行
- 一个方法内的两个逻辑段之间保留一个空行
空格
赋值符号
=
前后各一个空格例如
1
a = b;
所有二元运算符有应该使用空格与操作数分开
例如
1
a = b + c;
一元操作符(负号、自增、自减等)与操作数之间没有空格
例如
1
2a++;
--b;
左小括号
(
之后,右小括号)
之前不能有空格左大括号
{
之前应有一个空格例如
1
2
3public static void main(String[] args) {
}
方法参数列表左小括号
(
之前没有空格,右小括号)
之后有一个空格例如
1
2
3public static void test(int a) {
}
关键字之后紧跟着左小括号
(
,关键字之后应该有一个空格例如
1
2
3while (1) {
}
缩进
通常将4个空格作为缩进排版的一个单位
一般默认一个制表符(Tab)等于8个空格
不同 IDE 工具制表符与空格对应个数可能不同,IDEA 中默认一个制表符对应4个空格
方法、Lambda、控制语句等包含大括号 “ {} ” 的代码块中,代码块的内容相对于首行缩进一个制表符(Tab)
例如
1
2
3
4
5public class Date {
public void time() {
int year = super.getYear() + 1900;
}
}
if 语句中条件表达式的断行,新的一行应相对于上一行缩进两个指标都(Tab),再往后的断行应与第一次断行对齐
例如
1
2
3
4
5if ((a == b)
|| (c > d) && (e != f)
&& (g <= h)) {
}
断行
- 一行代码最好不要超过80个字符
- 断行规范
- 在一个逗号后断开
- 在一个操作符前断开,要选择较高级别的运算符
- 新的一行应相对于上一行索引两个制表符
其他规范
声明变量的时候最好一行声明一个
左大括号(“ { ”)位于声明语句同行的末尾,右大括号(“ } ”)另起一行,与相对应声明语句对齐;除非是一个空语句右大括号(“ } ”)应紧跟左大括号(“ { ”)之后
例如
1
2
3
4
5
6
7public static void main(String[] args) {
while (1) {
}
}
public static void setString() {}
每行最多包含一条语句
例如
1
2
3
4
5a++;
b--;
// 不推荐
a++; b--;
if、for 等控制语句在只有一行代码的情况下最好不要省略两个大括号
JAVA基础
JAVA基础语法
- 对象:类的一个实例,有状态和行为。例如:狗是一个对象,它的状态有颜色、名字、品种,行为有叫、吃、摇尾巴
- 类:类是一个模板,描述一类对象的行为和状态
- 方法:方法是行为,一个类可以有很多方法。逻辑运算以及所有动作都是在方法中完成的
- 实例变量:每个对象都有独特的实例变量,对象的状态由这些实例变量的值决定
第一个JAVA程序
1 | public class Test { |
- public:访问修饰符
- static:关键字
- void:返回类型
- main:方法名
- **String[]**:String类
- args:字符串数组
JAVA标识符
- 以字母、美元符($)、下划线(_)开始
- 首字母后可以是字母、美元符($)、下划线(_)或数字
- 关键字不能用作标识符
- 区分大小写
类和对象
- 对象:类的一个实例,有状态和行为。例如:狗是一个对象,它的状态有颜色、名字、品种,行为有叫、吃、摇尾巴
- 类:类是一个模板,描述一类对象的行为和状态
JAVA中的类
类可以看成是创建 Java 对象的模板
创建一个简单的类来理解下 Java 中类的定义:
1 | public class Dog { |
一个类可以包含以下类型变量:
- 局部变量:在方法、构造方法或语句块中定义的变量为局部变量。变量声明和初始化都是在方法中,方法结束后,变量会自动销毁
- 成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问
- 类变量:类变量也声明在类中,方法体之外,但必须声明static类型
构造方法
- 每个类都有构造方法
- 如果没有显式的为类定义构造方法,编译器会为该类提供一个默认的构造方法
- 创建一个对象的时候,至少要调用一个构造方法
- 构造方法的名称必须与类同名,一个类可以有多个构造方法
1 | public class Puppy{ |
创建对象
- 步骤:
- 声明:声明一个对象,包括对象名称和对象类型
- 实例化:用关键字 new 创建一个对象
- 初始化:使用 new 创建对象时,会调用构造方法初始化对象
1 | public class Object { |
结果:
1 | name:Tony |
访问实例变量和方法
1 | /* 实例化对象 */ |
实例
1 | public class Puppy{ |
结果:
1 | 小狗的名字是 : tommy |
源文件声明规则
- 一个源文件只能有一个public类
- 一个源文件可以有多个非public类
- 源文件的名称应该和 public 类的类名保持一致
- 如果一个类定义在某个包中,那么 package 语句应该在源文件的首行
- 如果源文件包含 import 语句,那么应该放在 package 语句和类定义之间;如果没有 package 语句,那么 import 语句应该在源文件中最前面
- import 语句和 package 语句对源文件中定义的所有类都有效
- 在同一源文件中,不能给不同的类不同的包声明
包
包主要用来对类和接口进行分类。当开发 Java 程序时,可能编写成百上千的类,因此很有必要对类和接口进行分类
import语句
- 在 Java 中,如果给出一个完整的限定名,包括包名、类名,那么 Java 编译器就可以很容易地定位到源代码或者类
- import 语句就是用来提供一个合理的路径,使得编译器可以找到某个类
下面的命令行将会命令编译器载入 java_installation/java/io 路径下的所有类
1 | import java.io.*; |
实践一下
- 创建两个类:Employee和EmployeeTest
- 程序都是从main方法开始执行。为了能运行这个程序,必须包含main方法并且创建一个实例对象
- EmployeeTest类,该类实例化2个 Employee 类的实例,并调用方法设置变量的值
1 | import java.io.*; |
1 | import java.io.*; |
1 | 姓名:One |
基本数据类型
整型
byte、short、int、long
- byte
- byte 数据类型是8位、有符号的,以二进制补码表示的整数
- 默认值是0
- byte 类型用在大型数组中节约空间,主要代替整数,因为 byte 变量占用的空间只有 int 类型的四分之一
- short
- short 数据类型是 16 位、有符号的以二进制补码表示的整数
- short 数据类型也可以像 byte 那样节省空间。一个short变量是int型变量所占空间的二分之一
- 默认值是0
- int
- int 数据类型是32位、有符号的以二进制补码表示的整数
- 一般地整型变量默认为 int 类型
- 默认值是0
- long
long 数据类型是 64 位、有符号的以二进制补码表示的整数
这种类型主要使用在需要比较大整数的系统上
默认值是 0L
声明
1
2long var1 = 16L;
long var2 = 16l;
浮点型
float、double
- float
- float 数据类型是单精度、32位、符合 IEEE 754 标准的浮点数
- float 在储存大型浮点数组的时候可节省内存空间
- 默认值是 0.0f
- 浮点数不能用来表示精确的值,如货币
- 声明的时候要在数值后家 F 或 f
- double
- double 数据类型是双精度、64 位、符合 IEEE 754 标准的浮点数
- 浮点数的默认类型为 double 类型
- double 类型同样不能表示精确的值,如货币
- 默认值是 0.0d
- 声明是数值后可以加上 D 或 d
布尔型
boolean
- boolean
- boolean 数据类型表示一位的信息
- 只有两个取值:true 和 false
- 这种类型只作为一种标志来记录 true/false 情况
- 默认值是 false
字符型
char
char
- char 类型是一个单一的 16 位 Unicode 字符
- char 数据类型可以储存任何字符
- 声明时字符常量必须是用单引号(“ ‘’ ”)括起来的单个字符
转义字符
数值表示方式
进制数值
- 二进制数:以 0b 或 0B 为前缀
- 八进制数:以 0 为前缀
- 十六进制数:以 0x 或 0X 为前缀
- 0 均为数字 0
指数
用 e 或 E 表示幂
幂前为底数,幂后为指数
e2 表示10的平方
例如
1
double myMoney = 3.36e2;
引用类型
- 在Java中,引用类型的变量非常类似于 C/C++ 的指针。引用类型指向一个对象,指向对象的变量是引用变量。这些变量在声明时被指定为一个特定的类型
- 对象、数组都是引用数据类型
- 所有引用类型的默认值都是null
- 一个引用变量可以用来引用任何与之兼容的类型
如:
1 | Employee empOne = new Employee("One"); |
引用类型比较
- Java 引用类型比较时,有 “ == ” 和 “ equals ” 两种方法
- “ == ” 比较的是两个引用是否指向同一个对象
- “ equals ” 比较的是对象内容是否相同
- 在枚举类型中 “ == ” 和 “ equals ” 是一样的,都是比较两个引用是否指向同一个实例,枚举类中每个枚举常量无论怎样都只有一个实例
常量
常量在程序运行时是不能被修改的
Java 中使用 final 关键字来修饰常量
1
final double PI = 3.14159;
通常使用大写字母表示常量
字符串常量和字符常量都可以包含任何Unicode字符
自动类型转换
转换从低级到高级
1
2
3低 -----------------------------------------> 高
byte -> short -> int -> long -> float -> double
char -> int -> long -> float -> double数据类型转换必须满足:
- 不能对boolean类型进行类型转换
- 不能把对象类型转换成不相关类的对象
- 在把容量大的类型转换为容量小的类型时必须使用强制类型转换
- 转换过程中可能导致溢出或损失精度
- 浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入
自动类型转换
必须满足转换前的数据类型的位数要低于转换后的数据类型
public class ZiDongLeiZhuan{
public static void main(String[] args){
char c1=’a’;//定义一个char类型
int i1 = c1;//char自动类型转换为int
System.out.println(“char自动类型转换为int后的值等于”+i1);
char c2 = ‘A’;//定义一个char类型
int i2 = c2+1;//char 类型和 int 类型计算
System.out.println(“char类型和int计算后的值等于”+i2);
}
}
1
char自动类型转换为int后的值等于97
char类型和int计算后的值等于66
1
2
3
4
5
6
7
8
9
- 强制类型转换
- 条件是转换的数据类型必须是兼容的
- 格式:
```java
(type) value- type 是要强制类型转换后的数据类型
public class QiangZhiZhuanHuan{
public static void main(String[] args){
int i1 = 123;
byte b = (byte)i1;//强制类型转换为byte
System.out.println(“int强制类型转换为byte后的值等于”+b);
}
}
1
int强制类型转换为byte后的值等于123
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- 隐含强制类型转换
- 整数的默认类型是 int
- 小数默认是 double 类型浮点型,在定义 float 类型时必须在数字后面跟上 F 或者 f
### 变量类型
- 所有的变量在使用前必须声明
声明变量的基本格式:
```java
type identifier [ = value][, identifier [= value] ...] ;type 为 Java 数据类型
identifier 是变量名
Java语言支持的变量类型:
- 类变量:独立于方法之外的变量,用 static 修饰
- 实例变量:独立于方法之外的变量,不过没有 static 修饰
- 局部变量:类的方法中的变量
局部变量
- 局部变量声明在方法、构造方法或者语句块中
- 局部变量在方法、构造方法、或者语句块被执行的时候创建,当它们执行完成后,变量将会被销毁
- 访问修饰符不能用于局部变量
- 局部变量只在声明它的方法、构造方法或者语句块中可见
- 局部变量是在栈上分配的
- 局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用
实例变量
- 实例变量声明在一个类中,但在方法、构造方法和语句块之外
- 当一个对象被实例化之后,每个实例变量的值就跟着确定
- 实例变量在对象创建的时候创建,在对象被销毁的时候销毁
- 实例变量的值应该至少被一个方法、构造方法或者语句块引用,使得外部能够通过这些方式获取实例变量信息
- 实例变量可以声明在使用前或者使用后
- 访问修饰符可以修饰实例变量
- 实例变量对于类中的方法、构造方法或者语句块是可见的。一般情况下应该把实例变量设为私有。通过使用访问修饰符可以使实例变量对子类可见
- 实例变量具有默认值。数值型变量的默认值是0,布尔型变量的默认值是false,引用类型变量的默认值是null。变量的值可以在声明时指定,也可以在构造方法中指定
- 实例变量可以直接通过变量名访问。但在静态方法以及其他类中,就应该使用完全限定名:ObejectReference.VariableName
1 | public class Employee{ |
1 | 名字 : RUNOOB |
类变量(静态变量)
- 在类中以 static 关键字声明,但必须在方法之外
- 无论一个类创建了多少个对象,类只拥有类变量的一份拷贝
- 静态变量除了被声明为常量外很少使用,静态变量是指声明为 public/private,final 和 static 类型的变量。静态变量初始化后不可改变
- 静态变量储存在静态存储区。经常被声明为常量,很少单独使用 static 声明变量
- 静态变量在第一次被访问时创建,在程序结束时销毁
- 与实例变量具有相似的可见性。但为了对类的使用者可见,大多数静态变量声明为 public 类型
- 默认值和实例变量相似。数值型变量默认值是 0,布尔型默认值是 false,引用类型默认值是 null。变量的值可以在声明的时候指定,也可以在构造方法中指定。此外,静态变量还可以在静态语句块中初始化
- 静态变量可以通过:ClassName.VariableName的方式访问
- 类变量被声明为 public static final 类型时,类变量名称一般建议使用大写字母。如果静态变量不是 public 和 final 类型,其命名方式与实例变量以及局部变量的命名方式一致
1 | public class Employee { |
1 | 开发人员平均工资:10000.0 |
修饰符
修饰符用来定义类、方法或变量,通常放在语句最前端
访问控制修饰符
- default:在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法
- private:在同一页内可见。适用对象:变量、方法。
- public:对所有类可见。使用对象:类、接口、变量、方法
- protected:对同一包内的类和所有子类可见。使用对象:变量、方法
默认访问修饰符–default
对同一个包内的类可见。
接口内的变量隐式声明为 public static final,接口内方法默认情况下访问权限为
public
1 | /* 变量和类的声明都没有加修饰符 */ |
私有访问修饰符–private
- 方法、变量和构造方法只能被所属类访问
- 类和接口不能声明为
private
- 声明为私有访问类型的变量只能通过类中公共的 getter 方法被外部类访问
1 | public class Logger { |
公有访问修饰符–public
- 类、方法、构造方法和接口能被任何其他类访问
- 如果几个相互访问的 public 类分布在不同的包中,则需要导入相应 public 类所在的包
- 类所有的公有方法和变量都能被其子类继承
- main() 方法必须设置为公有的
受保护的访问修饰符–protected
子类与基类在同一包中:被声明为 protected 的变量、方法和构造器能被同一个包中的任何其他类访问
子类与基类不在同一包中:在子类中,子类实例可以访问其从基类继承而来的 protected 方法,而不能访问基类实例的 protected 方法
protected 可以修饰数据成员,构造方法、方法成员,不能修饰类(除内部类)
接口及接口的成员变量和成员方法不能声明为 protected
子类能访问 protected 修饰符声明的方法和变量,这样就能保护不相关的类使用这些方法和变量
下面的父类使用了 protected 访问修饰符,子类重写了父类的 openSpeaker() 方法
1
2
3
4
5
6
7
8
9
10
11class AudioPlayer {
protected boolean openSpeaker(Speaker sp) {
// 实现细节
}
}
class StreamingAudioPlayer extends AudioPlayer {
protected boolean openSpeaker(Speaker sp) {
// 实现细节
}
}- 如果把 openSpeaker() 方法声明为 private,那么除了 AudioPlayer 之外的类将不能访问该方法
- 如果把 openSpeaker() 声明为 public,那么所有的类都能够访问该方法
- 如果我们只想让该方法对其所在类的子类可见,则将该方法声明为 protected
访问控制和继承
- 父类中声明为 public 的方法在子类中也必须为 public
- 父类中声明为 protected 的方法在子类中要么声明为 protected,要么声明为 public,不能声明为 private
- 父类中声明为 private 的方法,不能被子类继承
非访问修饰符
- static 修饰符,用来修饰类方法和类变量
- final修饰符,用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的
- abstract 修饰符,用来创建抽象类和抽象方法
- synchronized和 volatile 修饰符,主要用于线程的编程
static 修饰符
- 静态变量:static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。静态变量也被称为类变量。局部变量不能被声明为static变量
- 静态方法:static 关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据。然后计算这些数据
final 修饰符
final 变量
- 变量一旦赋值后,不能被重新赋值,被 final 修饰的实例变量必须显式指定初始值
- final 修饰符通常和 static 修饰符一起使用来创建类常量
final 方法
- 父类中的 final 方法可以被子类继承,但是不能被子类重写
- 声明 final 方法的主要目的是防止该方法的内容被修改
final 类
- final 类不能被继承,没有类能够继承 final 类的任何特性
abstract 修饰符
- 抽象类
- 抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充
- 一个类不能同时被 abstract 和 final 修饰
- 如果一个类包含抽象方法,那么该类一定要声明为抽象类
- 抽象类可以包含抽象方法和非抽象方法
- 抽象方法
- 抽象方法是一种没有任何实现的方法,该方法的具体实现由子类提供
- 抽象方法不能被声明成 final 和 static
- 任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类
- 如果一个类包含若干个抽象方法,那么该类必须声明为抽象类
- 抽象方法的声明以分号结尾,例如:public abstract sample();
synchronized 修饰符
- synchronized 关键字声明的方法同一时间只能被一个线程访问
- synchronized 修饰符可以应用于四个访问修饰符
transient 修饰符
- 序列化的对象包含被 transient 修饰的实例变量时,java 虚拟机(JVM)跳过该特定的变量
- 该修饰符包含在定义变量的语句中,用来预处理类和变量的数据类型
volatile 修饰符
- volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值
- 当成员变量发生变化时,会强制线程将变化值回写到共享内存
- 在任何时刻,两个不同的线程总是看到某个成员变量的同一个值
运算符
算数运算符
运算符 | 功能 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
% | 取模 |
++ | 自加1 |
– | 自减1 |
关系运算符
运算符 | 功能 |
---|---|
== | 等于 |
!= | 不等于 |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
位运算符
运算符 | 功能 |
---|---|
& | 如果相对应位都是1,结果为1,否则为0 |
| | 如果相对应位都是0,结果位0,否则为1 |
^ | 如果相对应位值相同,结果为0,否则为1 |
~ | 按位取反运算符翻转操作数的每一位 |
<< | 按位左运算符,左操作数按位左移右操作数指定的位数 |
>> | 按位右移运算符,左操作数按位右移右操作数指定的位数 |
>>> | 按位右移补零操作符,左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充 |
逻辑运算符
运算符 | 功能 | 说明 |
---|---|---|
! | 逻辑非 | !a => a 为 true,结果为 false,a 为 false,结果为 true |
& | 逻辑与 | a&b => a、b 均为 true,结果为 true,否则为 false |
| | 逻辑或 | a|b => a、b 均为 false,结果为 false,否则为 true |
&& | 短路与 | a&&b => a、b 均为 true,结果为 true,否则为 false;如果 a 为 false,则不计算 b,结果都为 false |
|| | 短路或 | a||b => a、b 均为 false,结果为 false,否则为 true;如果 a 为 true,则不计算 b,结果都为true |
赋值运算符
运算符 | 功能 |
---|---|
= | 赋值 |
+= | A+=B => A=A+B |
-= | A-=B => A=A-B |
*= | A * =B => A=A*B |
/= | A/=B => A=A/B |
(%)= | A%=B => A=A%B |
<<= | A<<=B => A=A<<B |
>>= | A>>=B => A=A>>B |
&= | A&=B => A=A&B |
^= | A^=B => A=A^B |
|= | A|=B => A=A|B |
条件运算符
1 | variable x = (expression) ? value if true : value if false |
instanceof 运算符
用于操作对象实例,检查该对象是否是一个特定类型(类类型或接口类型)
如果运算符左侧变量所指的对象,是操作符右侧类或接口(class/interface)的一个对象,那么结果为真
1 | ( Object reference variable ) instanceof (class/interface type) |
例:
1 | String name = "James"; |
如果被比较的对象兼容于右侧类型,该运算符仍然返回 true:
1 | class Vehicle {} |
循环
for 循环
1 | for(初始化;布尔表达式;更新) { |
while 循环
1 | while(布尔表达式) { |
do … while 循环
1 | do { |
增强 for 循环
主要用于数组
1 | for(声明语句:表达式) { |
声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等
表达式:表达式是要访问的数组名,或者是返回值为数组的方法
实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public class Test {
public static void main(String[] args){
int [] numbers = {10, 20, 30, 40, 50};
for(int x : numbers ){
System.out.print( x );
System.out.print(",");
}
System.out.print("\n");
String [] names ={"James", "Larry", "Tom", "Lacy"};
for( String name : names ) {
System.out.print( name );
System.out.print(",");
}
}
}1
210,20,30,40,50,
James,Larry,Tom,Lacy,
continue 关键字
适用于任何循环控制结构中
让程序立刻跳转到下一次循环的迭代
break 关键字
主要用在循环语句或者 switch 语句中
用来跳出整个语句块
break 跳出最里层的循环,并且继续执行该循环下面的语句
条件语句
if 语句
1 | if(布尔表达式) { |
if … else 语句
1 | if(布尔表达式) { |
if … else if … else 语句
1 | if(布尔表达式1) { |
switch 语句
1 | switch(value) { |
- switch case 执行时,一定会先进行匹配,匹配成功返回当前 case 的值,再根据是否有 break,判断是否继续输出,或是跳出判断
- 当遇到 break 语句时,switch 语句终止。程序跳转到 switch 语句后面的语句执行。case 语句不必须要包含 break 语句。如果没有 break 语句出现,程序会继续执行下一条 case 语句,直到出现 break 语句
- 如果 case 语句块中没有 break 语句时,JVM 并不会顺序输出每一个 case 对应的返回值,而是继续匹配,匹配不成功则返回默认 case
- 如果 case 语句块中没有 break 语句时,匹配成功后,从当前 case 开始,后续所有 case 的值都会输出
- 如果当前匹配成功的 case 语句块没有 break 语句,则从当前 case 开始,后续所有 case 的值都会输出,如果后续的 case 语句块有 break 语句则会跳出判断
Number 和 Math 类
Number 类
所有的包装类(Integer、Long、Byte、Double、Float、Short)都是抽象类 Number 的子类
- 这种由编译器特别支持的包装称为装箱
- 当内置数据类型被当作对象使用的时候,编译器会把内置类型装箱为包装类
- 编译器也可以把一个对象拆箱为内置类型
- Number 类属于 java.lang 包
Math 类
包含了用于执行基本数学运算的属性和方法,如初等指数、对数、平方根和三角函数
Math 的方法都被定义为 static 形式,通过 Math 类可以在主函数中直接调用
实例:
1 | public class Test { |
1 | 90 度的正弦值:1.0 |
Number 和 Math 类方法
方法 | 功能 |
---|---|
xxxValue() | 将 Number 对象转换为xxx数据类型的值并返回 |
compareTo() | 将number对象与参数比较 |
equals() | 判断number对象是否与参数相等 |
valueOf() | 返回一个 Number 对象指定的内置数据类型 |
toString() | 以字符串形式返回值 |
parselInt() | 将字符串解析为int类型 |
abs() | 返回参数的绝对值 |
ceil() | 返回大于等于( >= )给定参数的的最小整数,类型为双精度浮点型 |
floor() | 返回小于等于(<=)给定参数的最大整数 |
rint() | 返回与参数最接近的整数(返回值类型为double) |
round() | 它表示四舍五入,算法为 **Math.floor(x+0.5)**,即将原来的数字加上 0.5 后再向下取整,所以,Math.round(11.5) 的结果为12,Math.round(-11.5) 的结果为-11 |
min() | 返回两个参数中的最小值 |
max() | 返回两个参数中的最大值 |
exp() | 返回自然数底数e的参数次方 |
log() | 返回参数的自然数底数的对数值 |
pow() | 返回第一个参数的第二个参数次方 |
sqrt() | 求参数的算术平方根 |
sin() | 求指定double类型参数的正弦值 |
cos() | 求指定double类型参数的余弦值 |
tan() | 求指定double类型参数的正切值 |
asin() | 求指定double类型参数的反正弦值 |
acos() | 求指定double类型参数的反余弦值 |
atan() | 求指定double类型参数的反正切值 |
atan2() | 将笛卡尔坐标转换为极坐标,并返回极坐标的角度值 |
toDegress() | 将参数转化为角度 |
toRadians() | 将角度转换为弧度 |
random() | 返回一个随机数 |
Math 的 floor,round 和 ceil 方法
参数 | Math.floor() | Math.round() | Math.ceil() |
---|---|---|---|
1.4 | 1 | 1 | 2 |
1.5 | 1 | 2 | 2 |
1.6 | 1 | 2 | 2 |
-1.4 | 2 | -1 | -1 |
-1.5 | 2 | -1 | -1 |
-1.6 | 2 | -2 | -1 |
Character 类
用于对单个字符进行操作
在对象中包装一个基本类型 char 的值
实例:
1
2
3
4
5
6
7char ch = 'a';
// Unicode 字符表示形式
char uniChar = '\u039A';
// 字符数组
char[] charArray ={ 'a', 'b', 'c', 'd', 'e' };为了解决需要使用对象,而不是内置数据类型的情况,java 语言为内置数据类型 char 提供了包装类 Character 类
Character 类提供了一系列方法来操纵字符。你可以使用 Character 的构造方法创建一个 Character 类对象
1
Character ch = new Character('a');
在某些情况下,Java 编译器会自动创建一个 Character 对象
例如,将一个 char 类型的参数传递给需要一个 Character 类型参数的方法时,那么编译器会自动地将char类型参数转换为Character 对象
这种特征称为装箱,反过来称为拆箱
实例:
1
2
3
4
5
6// 原始字符 'a' 装箱到 Character 对象 ch 中
Character ch = 'a';
// 原始字符 'x' 用 test 方法装箱
// 返回拆箱的值到 'c'
char c = test('x');
转义序列
转义序列 | 功能 |
---|---|
\t | 在文中该处插入一个tab键 |
\b | 在文中该处插入一个后退键 |
\n | 在文中该处换行 |
\r | 在文中该处插入回车 |
\f | 在文中该处插入换页符 |
\ ‘ | 在文中该处插入单引号 |
\ “ | 在文中该处插入双引号 |
\ \ | 在文中该处插入反斜杠 |
Character 方法
方法 | 功能 |
---|---|
isLetter() | 是否是一个字母 |
isDigit() | 是否是一个数字字符 |
isWhitespace() | 是否是一个空白字符 |
isUpperCase() | 是否是大写字母 |
isLowerCase() | 是否是小写字母 |
toUpperCase() | 指定字母的大写形式 |
toLowerCase() | 指定字母的小写形式 |
toString() | 返回字符的字符串形式,字符串的长度仅为1 |
字符串
用双引号括起来的多个字符
1 | "Hello World!" |
- 空字符串不是 null ,空字符串是分配内存空间,null 是没有分配内存空间
不可变字符串
String
创建字符串
1
String strName="str";
用构造函数创建字符串
1
2
3
4
5// 使用空字符串创建并初始化一个新的 String 对象
String strName=new String();
// 使用另外一个字符串创建并初始化一个新的 String 对象
String staName = new String(String original);String(StringBuffer buffer)
:使用可变字符串对象(StringBuffer)创建并初始化一个新的 String 对象String(StringBuilder builder)
:使用可变字符串对象(StringBuilder)创建并初始化一个新的 String 对象String(byte[] bytes)
:使用平台默认的字符集解码指定的 byte 数组,通过 byte 数组创建并初始化一个新的 String 对象String(char[] value)
:通过字符数组创建并初始化一个新的 String 对象String(char[] calue, int offset, int count)
:通过字符数组的子数组创建并初始化一个新的 String 对象offset:子数组第一个字符的索引
count:指定子数组的长度
实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20// 创建字符串对象
String str1 = new String();
String str2 = new String("Hello World");
String str3 = new String("\u0048\u0065\u006c\u006c\u006f");
System.out.println("str2 = " + str2);
System.out.println("str3 = " + str3);
char[] chars = {'a', 'b', 'c', 'd', 'e', 'f', 'g'};
// 通过字符数组创建字符串对象
String str4 = new String(chars);
// 通过子字符数组创建字符串对象
String str5 = new String(chars, 1, 4);
System.out.println("str4 = " + str4);
System.out.println("str5 = " + str5);
byte[] bytes = { 97, 98, 99 };
// 通过 byte 数组创建字符串对象
String str6 = new String(bytes);
System.out.println("str6 = " + str6);
System.out.println("str6 的长度:" + str6.length());1
2
3
4
5
6str2 = Hello World
str3 = Hello
str4 = abcdefg
str5 = bcde
str6 = abc
str6 的长度:3
字符串池
1 | String str1 = "Hello"; // 字符串常量 |
1 | str1 == str2 : true |

字符串长度
1 | strName.length(); |
连接字符串
使用 “ + ” 拼接
优势:可以拼接任何类型的数据成字符串
1
str1 + str2;
使用 contact(String str) 拼接
是能拼接 String 型数据
1
str1.contact(str2);
创建格式化字符串
可以使用 printf() 和 format() 方法
String 类使用静态方法 format() 返回一个String 对象而不是 PrintStream 对象
String 类的静态方法 format() 能用来创建可复用的格式化字符串,而不仅仅是用于一次打印输出
使用 printf() 方法
1
2
3
4System.out.printf("浮点型变量的值为 " +
"%f, 整型变量的值为 " +
" %d, 字符串变量的值为 " +
"is %s", floatVar, intVar, stringVar);使用 format() 方法
1
2
3
4
5String fs;
fs = String.format("浮点型变量的值为 " +
"%f, 整型变量的值为 " +
" %d, 字符串变量的值为 " +
" %s", floatVar, intVar, stringVar);
StringBuffer 和 StringBuilder 类
在对字符串进行修改时使用
StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象

在使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,所以如果需要对字符串进行修改推荐使用 StringBuffer
StringBulider 和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)
由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类
实例
1
2
3
4
5
6
7
8
9
10
11
12
13public class RunoobTest{
public static void main(String args[]){
StringBuilder sb = new StringBuilder(10);
sb.append("Runoob..");
System.out.println(sb);
sb.append("!");
System.out.println(sb);
sb.insert(8, "Java");
System.out.println(sb);
sb.delete(5,8);
System.out.println(sb);
}
}1
2
3
4Runoob..
Runoob..!
Runoob..Java!
RunooJava!在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类
数组
声明数组
1 | // 方法一(首选) |
数组初始化
静态初始化
例如
1
2int[] intArray = {1,2,3,4};
String[] strArray = {'a','b','c','d'};
动态初始化
- 使用 new 操作符创建数组
1
new dataType[arraySize]
- 用一条语句完成数组声明和创建
1
2
3
4dataType[] arrayName = new dataType[arraySize];
// 也可以这样创建数组
dataType[] arrayName = {value0,value2,[...,]valuen};
for-each 循环
可以在不使用下标的情况下遍历数组
1 | for(type element: array) |
多维数组
多维数组可以看成是数组的数组
比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组
二维数组声明
1 | // 方法一,最常用 |
初始化
静态初始化
例如
1
int[][] intArray = { {1,2,3}, {4,5,6}, {7,8,9} };
动态初始化
使用 new 操作符初始化
1
new dataType[rowsNum][colsNum]
用一条语句完成声明和初始化
1
dataType[][] arrayName = new dataType[rowsNum][colsNum];
Array 类
能方便地操作数组,它提供的所有方法都是静态的
- 功能
- 给数组赋值:通过 fill 方法
- 对数组排序:通过 sort 方法,按升序
- 比较数组:通过 equals 方法比较数组中元素值是否相等
- 查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作
方法
方法 | 功能 |
---|---|
public static int binarySearch(Object[] a, Object key) | 用二分查找算法在给定数组中搜索给定值的对象(Byte,Int,double等)。数组在调用前必须排序好的。如果查找值包含在数组中,则返回搜索键的索引;否则返回 (-(插入点) - 1) |
public static boolean equals(long[] a, long[] a2) | 如果两个指定的 long 型数组彼此相等,则返回 true。如果两个数组包含相同数量的元素,并且两个数组中的所有相应元素对都是相等的,则认为这两个数组是相等的。换句话说,如果两个数组以相同顺序包含相同的元素,则两个数组是相等的。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等) |
public static void fill(int[] a, int val) | 将指定的 int 值分配给指定 int 型数组指定范围中的每个元素。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等) |
public static void sort(Object[] a) | 对指定对象数组根据其元素的自然顺序进行升序排列。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等) |