一、Java语言发展简史
二、Java语言特性
1、简单性
Java语法是C++语法的一个“纯净版本”,相当于对C++做了一个减法。这里没有头文件、指针运算(甚至指针语法)、结构、联合、操作符重载、虚基类等等。不仅如此,Java开发环境远远超出大多数其他编程语言的开发环境。
三、初认Java
3.1 Java结构
- 源文件(扩展名为*.java):源文件带有类的定义。类用来表示程序的一个组件,小程序或许只会有一个 类。类的内容必须包含在花括号里面。
- 类:类中带有一个或多个方法。方法必须在类的内部声明。
- 方法:在方法的花括号中编写方法应该执行的语句。
3.2 运行java程序
- JDK(Java Development Kit):Java开发工具包,提供给Java程序员使用,包含了JRE,同时还包含了编译器javac与自带的调试工具Jconsole、jstack等。
- JRE(Java Runtime Environment):Java运行时环境,包含了JVM,Java基础类库。是使用Java语言编写程序运行的所需环境。
- JVM:Java虚拟机,运行Java代码

3.3 注释
- 单行注释:// 注释内容(用的最多)
- 多行注释:/* 注释内容*/
- 文档注释: /** 文档注释 */(常见于方法和类之上描述方法和类的作用),可以被javadoc工具解析,生成一套以网页文件形式体现的程序说明文档
- 多行注释不能嵌套使用
- 不论是单行还是多行注释,都不参与编译,即编译之后生成的.class文件中不包含注释信息。
3.4 标识符
- 类名:每个单词的首字母大写(大驼峰)
- 方法名:首字母小写,后面每个单词的首字母大写(小驼峰)
- 变量名:与方法名规则相同
3.5 关键字
class | extends | implements | interface | inport |
package | break | case | continue | default |
do | if | else | for | return |
switch | while | false | short | null |
boolean | byte | char | try | int |
long | float | double | abstract | catch |
throw | throws | finally | public | final |
native | private | protected | instance of | static |
synchronized | transient | volatile | true | new |
super | void | assert | enum | goto |
const |
注:在Java中关键字都是小写的。
3.6 数据类型与变量
3.6.1 字面常量
- 字符串常量:由""括起来的,比如“12345”、“hello”、“你好”。
- 整形常量:程序中直接写的数字(注意没有小数点),比如:100、1000
- 浮点数常量:程序中直接写的小数,比如:3.14、0.34
- 字符常量:由 单引号 括起来的当个字符,比如:‘A’、‘1’
- 布尔常量:只有两种true和false
- 空常量:null
3.6.2 数据类型
- 四类:整型、浮点型、字符型以及布尔型
- 八种:

- 不论是在16位系统还是32位系统,int都占用4个字节,long都占8个字节
- 整形和浮点型都是带有符号的
- 整型默认为int型,浮点型默认为double
- 字符串属于引用类型
3.6.3 类型转换
int a = 100;
long b = 10L;
//a和b都是整形,a的范围小,b的范围大,当将a赋值给b时,编译器会自动将a提升为long类型,然后赋值
b = a;
//编译报错,long的范围比int范围大,会有数据丢失,不安全
a = b;
(2)强制类型转换(显式)
int a = 10;
long b = 100L;
//int—>long,数据范围由小到大,隐式转换
b = a;
//long—>int,数据范围由大到小,需要强转,否则编译失败
a = (int)b;
- 不同数字类型的变量之间赋值, 表示范围更小的类型能隐式转换成范围较大的类型
- 如果需要把范围大的类型赋值给范围小的, 需要强制类型转换, 但是可能精度丢失
- 将一个字面值常量进行赋值的时候, Java 会自动针对数字范围进行检查
- 强制类型转换不一定能成功,不相干的类型不能互相转换
3.6.4 类型提升
不同类型的数据之间相互运算时,数据类型小的会被提升到数据类型大的。
(1) int与long之间:int会被提升为long
int a = 10;
long b = 20;
int c = a + b; // 编译出错: a + b==>int + long--> long + long 赋值给int时会丢失数据
long d = a + b; // 编译成功:a + b==>int + long--->long + long 赋值给long
(2) byte与byte的运算
byte a = 10;
byte b = 20;
byte c = a + b;
System.out.println(c);
// 编译报错,不兼容的类型: 从int转换到byte可能会有损失
//以下是正确的写法
byte c = (byte)(a + b);
- 不同类型的数据混合运算, 范围小的会提升成范围大的.
- 对于 short, byte 这种比 4 个字节小的类型, 会先提升成 4 个字节的 int , 再运算.
3.7 字符串类型
在Java中使用String类定义字符串类型
int num = 10;
//方法1
String str1 = num + "";
//方法2
String str2 = String.valueOf(num);
String str = "100";
int num = Integer.parseInt(str);
3.7 运算符
3.7.1 算术运算符
(1) 基本四则运算符:加减乘除模(+-*/%)
int a = 20;
int b = 10;
System.out.println(a + b); // 30
System.out.println(a - b); // 10
System.out.println(a * b); // 200
System.out.println(a / b); // 2
System.out.println(a % b); // 0 --->模运算相当于数学中除法的余数
- 都是二元运算符,使用时必须要有左右两个操作数
- int / int 结果还是int类型,而且会向下取整
- 做除法和取模时,右操作数不能为0
- % 不仅可以对整形取模,也可以对double类型取模,但是没有意义,一般都是对整形取模的
System.out.println(11.5 % 2.0);
// 运行结果
1.5
- 两侧操作数类型不一致时,向类型大的提升
// +的左侧是int,右侧是double,在加之前int被提升为double.故:输出1.2
System.out.println(1+0.2);
3.7.2 增量运算符
int a = 1;
a += 2; // 相当于 a = a + 2
System.out.println(a); // 输出3
3.7.3 自增/自减运算符 ++ --
int a = 1;
a++; // 后置++ 表示给a的值加1,此时a的值为2
System.out.println(a++); // 注意:后置++是先使用变量原来值,表示式结束时给变量+1,因此输出2
System.out.println(a); // 输出3
++a; // 前置++ 表示给a的值加1
System.out.println(++a); // 注意:前置++是先给变量+1,然后使用变量中的值,因此输出5
System.out.println(a); // 输出5
// --操作符给操作-1,与++含义类似
- 如果单独使用,【前置++】和【后置++】没有任何区别
- 如果混合使用,【前置++】先+1,然后使用变量+1之后的值,【后置++】先使用变量原来的值,表达式 结束时给变量+1
3.7.4 关系运算符
int a = 1;
int b = 2;
// 注意:在Java中 = 表示赋值,要与数学中的含义区分
// 在Java中 == 表示相等
System.out.println(a == b); // false
System.out.println(a != b); // true
System.out.println(a < b); // true
System.out.println(a > b); // false
System.out.println(a <= b); // true
System.out.println(a >= b); // false
3.7.5 逻辑运算符
System.out.println(10 > 20 && 10 / 0 == 0); // 打印 false
System.out.println(10 < 20 || 10 / 0 == 0); // 打印 true
- 对于 && , 如果左侧表达式值为 false, 则表达式结果一定是 false, 无需计算右侧表达式.
- 对于 ||, 如果左侧表达式值为 true, 则表达式结果一定是 true, 无需计算右侧表达式.
- & 和 | 如果表达式结果为 boolean 时, 也表示逻辑运算. 但与 && || 相比, 它们不支持短路求值.
System.out.println(10 > 20 & 10 / 0 == 0); // 程序抛出异常
System.out.println(10 < 20 | 10 / 0 == 0); // 程序抛出异常
3.7.6 位运算符
(1)按位与 &: 如果两个二进制位都是 1, 则结果为 1, 否则结果为 0.
(2)按位或 |: 如果两个二进制位都是 0, 则结果为 0, 否则结果为 1.
注意: 当 & 和 | 的操作数为整数(int, short, long, byte) 的时候, 表示按位运算, 当操作数为 boolean 的时候, 表 示逻辑运算.
(3)按位取反 ~: 如果该位为 0 则转为 1, 如果该位为 1 则转为 0
(4)按位异或 ^: 如果两个数字的二进制位相同, 则结果为 0, 相异则结果为 1.
注意:如果两个数相同,则异或的结果为0
3.7.7 条件运算符
// 求两个整数的最大值
int a = 10;
int b = 20;
int max = a > b ? a : b;
- 1. 表达式2和表达式3的结果要是同类型的,除非能发生类型隐式类型转换
- 2. 表达式不能单独存在,其产生的结果必须要被使用
3.7.8 运算符的优先级
3.8 逻辑控制
3.8.1 顺序结构
3.8.2 分支结构
if(布尔表达式1){
// 语句1
}else if(布尔表达式2){
// 语句2
}else{
// 语句3
}
switch(表达式){
case 常量值1:{
语句1;
[break;]
}
case 常量值2:{
语句2;
[break;]
}
...
default:{
内容都不满足时执行语句;
[break;]
}
}
- 先计算表达式的值
- 和case依次比较,一旦有响应的匹配就执行该项下的语句,直到遇到break时结束
- 当表达式的值没有与所列项匹配时,执行default
- 多个case后的常量值不可以重复
- switch的括号内只能是以下类型的表达式:
3.8.3 循环结构
while(循环条件){
循环语句;
}
for(表达式①;布尔表达式②;表达式③){
表达式④;
}
do{
循环语句;
}while(循环条件);
- do while 循环最后的分号不要忘记
- 一般 do while 很少用到, 更推荐使用 for 和 while.
四、Java进阶
4.1方法的使用
4.1.1方法的定义
// 方法定义
修饰符 返回值类型 方法名称([参数类型 形参 ...]){
方法体代码;
[return 返回值];
}
- 在java当中,没有方法声明一说
- 返回值类型:如果方法有返回值,返回值类型必须要与返回的实体类型一致,如果没有返回值,必须写成 void
- 方法名字:采用小驼峰命名
- 参数列表:如果方法没有参数,()中什么都不写,如果有参数,需指定参数类型,多个参数之间使用逗号隔开
- 方法体:方法内部要执行的语句
- 在java当中,方法必须写在类当中
- 在java当中,方法不能嵌套定义
- 定义方法的时候, 不会执行方法的代码. 只有调用的时候才会执行.
- 一个方法可以被多次调用.
4.1.2 实参和形参的关系
public class TestMethod {
public static void main(String[] args) {
int a = 10;
int b = 20;
swap(a, b);
System.out.println("main: a = " + a + " b = " + b);
}
public static void swap(int x, int y) {
int tmp = x;
x = y;
y = tmp;
System.out.println("swap: x = " + x + " y = " + y);
}
}
// 运行结果
swap: x = 20 y = 10
main: a = 10 b = 20
4.1.3 方法重载
public class TestMethod {
public static void main(String[] args) {
add(1, 2); // 调用add(int, int)
add(1.5, 2.5); // 调用add(double, double)
add(1.5, 2.5, 3.5); // 调用add(double, double, double)
}
public static int add(int x, int y) {
return x + y;
}
public static double add(double x, double y) {
return x + y;
}
public static double add(double x, double y, double z) {
return x + y + z;
}
}
- 方法名必须相同
- 参数列表必须不同(参数的个数不同、参数的类型不同、类型的次序必须不同)
- 与返回值类型是否相同无关
- 编译器在编译代码时,会对实参类型进行推演,根据推演的结果来确定调用哪个方法
4.1.4 方法签名
4.1.5 递归
- 将原问题划分成其子问题,注意:子问题必须要与原问题的解法相同
- 递归出口
4.2 数组的定义与使用
4.2.1 什么是数组
4.2.2 数组的创建
T[] 数组名 = new T[N];
- T:表示数组中存放元素的类型
- T[]:表示数组的类型
- N:表示数组的长度
4.2.3 数组的初始化
int[] array = new int[5];
int[] array = new int[]{0,1,2,3,4,5,6,7,8,9};
- 静态初始化虽然没有指定数组的长度,编译器在编译时会根据{}中元素个数来确定数组的长度。
- 静态初始化时, {}中数据类型必须与[]前数据类型一致。
- 静态初始化可以简写,省去后面的new T[]。
// 注意:虽然省去了new T[], 但是编译器编译代码时还是会还原
int[] array1 = {0,1,2,3,4,5,6,7,8,9};
- 静态和动态初始化也可以分为两步,但是省略格式不可以
int[] array1;
array1 = new int[10];
int[] array2;
array2 = new int[]{10, 20, 30};
// 注意省略格式不可以拆分, 否则编译失败
// int[] array3;
// array3 = {1, 2, 3};
- 如果没有对数组进行初始化,数组中元素有其默认值
- 如果数组中存储元素类型为基类类型,默认值为基类类型对应的默认值,比如:
类型 | 默认值 |
byte | 0 |
short | 0 |
int | 0 |
long
| 0 |
float | 0.0f |
double | 0.0 |
char |
/u0000
|
boolean | false |
- 如果数组中存储元素类型为引用类型,默认值为null
4.2.4 数组的使用
- 数组是一段连续的内存空间,因此支持随机访问,即通过下标访问快速访问数组中任意位置的元素
- 下标从0开始,介于[0, N)之间不包含N,N为元素个数,不能越界,否则会报出下标越界异常。
- 数组是引用类型
- 程序计数器 (PC Register): 只是一个很小的空间, 保存下一条执行的指令的地址
- 虚拟机栈(JVM Stack): 与方法调用相关的一些信息,每个方法在执行时,都会先创建一个栈帧,栈帧中包含 有:局部变量表、操作数栈、动态链接、返回地址以及其他的一些信息,保存的都是与方法执行时相关的一 些信息。比如:局部变量。当方法运行结束后,栈帧就被销毁了,即栈帧中保存的数据也被销毁了。
- 本地方法栈(Native Method Stack): 本地方法栈与虚拟机栈的作用类似. 只不过保存的内容是Native方法的局部变量. 在有些版本的 JVM 实现中(例如HotSpot), 本地方法栈和虚拟机栈是一起的
- 堆(Heap): JVM所管理的最大内存区域. 使用 new 创建的对象都是在堆上保存 (例如前面的 new int[]{1, 2, 3} ),堆是随着程序开始运行时而创建,随着程序的退出而销毁,堆中的数据只要还有在使用,就不会被销毁。
- 方法区(Method Area): 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据. 方法编译出的的字节码就是保存在这个区域 。
public static void func() {
int a = 10;
int b = 20;
int[] arr = new int[]{1,2,3};
}
注意:
- null 在 Java 中表示 "空引用" , 也就是一个不指向对象的引用.
- null 的作用类似于 C 语言中的 NULL (空指针), 都是表示一个无效的内存位置. 因此不能对这个内存进行任何读写操 作. 一旦尝试读写, 就会抛出 NullPointerException.
// 创建类
class ClassName{
field; // 字段(属性) 或者 成员变量
method; // 行为 或者 成员方法
}
8. 构造方法的作用就是对对象中的成员进行初始化,并不负责给对象开辟空间。
4.3.6 默认初始化
局部变量在使用时必须要初始化,而成员变量可以不用。
4.3.7 封装
1、访问控制权限控制符包括:
public 表示公开的,在任何位置都可以访问
protected 同包,子类
缺省 同包
private 表示私有的,只能在本类中访问
2、访问控制修饰符可以修饰类、变量、方法......
3、当某个数据只希望子类使用,使用protected进行修饰。
4、修饰符的范围:
private < 缺省 < protected < public