JavaSE系列上篇-大佬请移步

104 阅读17分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情

本文是本人整理出来的学习笔记,只适合用于 Java初学者 的多次复习,目的在于尽可能帮助初学者理清JavaSE整个体系的脉络,这是SE系列的三分之一,不足之处请多包含。

01-Java的源头

1.1 Java是什么?

Java 是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 面向对象程序设计语言和 Java 平台的总称。由 James Gosling和同事们共同研发,并在 1995 年正式推出。

后来 Sun 公司被 Oracle (甲骨文)公司收购,Java 也随之成为 Oracle 公司的产品。

1.2 Java的体系

Java分为三个体系:

  • JavaSE(J2SE)(Java2 Platform Standard Edition,java平台标准版)

是其他两个版本的基础。

  • JavaEE(J2EE)(Java 2 Platform,Enterprise Edition,java平台企业版)

用于Web方向的网站开发。(主要从事后台服务器的开发)

在服务器领域,Java是当之无愧的龙头老大。

  • JavaME(J2ME)(Java 2 Platform Micro Edition,java平台微型版)。

Java语言的小型版,用于嵌入式消费类电子设备或者小型移动设备的开发。

其中最为主要的还是小型移动设备的开发(手机)。渐渐的没落了,已经被安卓和IOS给替代了。

但是,安卓也是可以用Java来开发的。

2005 年 6 月,JavaOne 大会召开,SUN 公司公开 Java SE 6。此时,Java 的各种版本已经更名,以取消其中的数字 "2":J2EE 更名为 Java EE,J2SE 更名为Java SE,J2ME 更名为 Java ME。

1.3 Java特性和优势

  • 简单性
  • 面向对象
  • 可移植性
  • 高性能
  • 分布式
  • 动态性
  • 多线程
  • 安全性
  • 健壮性

1.4 编译型和解释型语言

编译型:

有的编程语言要求必须提前将所有源代码一次性转换成二进制指令,也就是生成一个可执行程序(Windows 下的 .exe),比如C语言、C++、Golang、Pascal(Delphi)、汇编等,这种编程语言称为编译型语言,使用的转换工具称为编译器

解释型:

有的编程语言可以一边执行一边转换,需要哪些源代码就转换哪些源代码,不会生成可执行程序,比如 Python、JavaScript、PHP、Shell、MATLAB 等,这种编程语言称为解释型语言,使用的转换工具称为解释器

1.5 JDK、JRE、JVM

JDK( Java Development Kit

它用于开发 Java 应用程序的软件开发工具,包括了 Java 运行时的环境(JRE)、解释器(Java)、编译器(javac)、Java 归档(jar ——一种软件包文件格式)、文档生成器(Javadoc)等工具。

JRE( Java Runtime Enviroment

它提供 Java 应用程序执行时所需的环境,由 Java 虚拟机(JVM)、核心类、支持文件组成。

JVM( Java Virtual Machine(Java 虚拟机)

它有三层含义,分别是:

  • JVM规范要求
  • 满足 JVM 规范要求的一种具体实现(一种计算机程序)
  • 一个 JVM 运行实例,在命令提示符下编写 Java 命令以运行 Java 类时,都会创建一个 JVM 实例。

三者之间的关系

  • JDK = JRE + 开发工具
  • JRE = JVM + 类库

1.6 Java语言跨平台的原理

  • 操作系统本身其实是不认识Java语言的。
  • 但是针对于不同的操作系统,Java提供了不同的虚拟机。

虚拟机 会把Java语言翻译成操作系统能看得懂的语言。

02-Java基础语法

2.1 编码规范

必须按照规范编写代码,否则程序会出错

  1. Java程序的文件名和类名必须保持一致。
  2. main方法必须按照格式编写
  3. 类是组织Java代码结构的,类中的方法是执行业务逻辑的,类和方法都必须使用{}组织其结构,而且必须成对出现,缺一不可。

2.1-1 建议编码规范

  • 一行只写一条语句
  • 注意代码的缩进

2.1-2 小驼峰命名法

适用于变量名和方法名

  • 如果是一个单词,那么全部小写,比如:name
  • 如果是多个单词,那么从第二个单词开始,首字母大写,比如:firstName、maxAge

2.1-3 大驼峰命名法

适用于类名

  • 如果是一个单词,那么首字母大写。比如:Demo、Test。
  • 如果是多个单词,那么每一个单词首字母都需要大写。比如:HelloWorld

不管起什么名字,都要做到见名知意。

2.1-4 阿里巴巴命名规范细节:

  1. 尽量不要用拼音。但是一些国际通用的拼音可视为英文单词。

正确:alibaba、hangzhou、nanjing 错误:jiage、dazhe

  1. 平时在给变量名、方法名、类名起名字的时候,不要使用下划线或美元符号。

错误:_name正确:name

2.2 注 释

注释可以是编程思路,也可以是功能的描述或者程序的作用,总之就是对代码的进一步阐述。

注释内容不会参加编译和运行,仅仅是对代码的解释说明。

注释分类格式
单行注释//注释信息
多行注释/注释信息/
文档注释/注释信息/

2.3 关键字(了解即可)

  • 被Java赋予了特定涵义的英文单词
  • 关键字的字母全部是小写

Class关键字表示定义一个类,后面跟随类名。

大致说明一下

abstract class extends implements null strictfp true assert const false import package super try boolean continue final instanceof private switch void break default finally int protected synchronized volatile byte do float interface public this while case double for long return throw catch else goto native short throws char enum if new static transient

2.4 常量

常量:在程序运行过程中,其值不可以发生改变的量。

Java中的常量分类:

  • 字符串常量 用双引号括起来的多个字符(可以包含0个、一个或多个),例如"a"、"abc"、"中国"等
  • 整数常量 整数,例如:-10、0、88等
  • 小数常量 小数,例如:-5.5、1.0、88.88等
  • 字符常量 用单引号括起来的一个字符,例如:'a'、'5'、'B'、'中'等
  • 布尔常量 布尔值,表示真假,只有两个值true和false
  • 空常量 一个特殊的值,空值,值为null
  • 除空常量外,其他常量均可使用输出语句直接输出。
public class Demo {
    public static void main(String[] args) {
        System.out.println(10); // 输出一个整数
        System.out.println(5.5); // 输出一个小数
        System.out.println('a'); // 输出一个字符
        System.out.println(true); // 输出boolean值true
        System.out.println("你好,世界!"); // 输出字符串
    }
}

2.5 数据类型

2.5-1 基本数据类型

数据类型关键字内存占用取值范围
整数byte1负的2的7次方 ~ 2的7次方-1(-128~127)
short2负的2的15次方 ~ 2的15次方-1(-32768~32767)
int(默认)4负的2的31次方 ~ 2的31次方-1
long8负的2的63次方 ~ 2的63次方-1
浮点数float41.401298e-45 ~ 3.402823e+38
double(默认)84.9000000e-324 ~ 1.797693e+308
字符char20-65535
布尔boolean1true,false

2.6 变量

2.6-1 变量的定义

变量:在程序运行过程中,其值可以发生改变的量。

从本质上讲,变量是内存中的一小块区域,其值可以在一定范围内变化。

变量的定义格式:

数据类型 变量名 = 初始化值; // 声明变量并赋值
int age = 18;
System.out.println(age);

变量的使用:通过变量名访问即可。

2.6-2 使用变量时的注意事项

  1. 在同一对花括号中,变量名不能重复。
  2. 变量在使用之前,必须初始化(赋值)。
  3. 定义long类型的变量时,需要在整数的后面加L(大小写均可,建议大写)。因为整数默认是int类型,整数太大可能超出int范围。
  4. 定义float类型的变量时,需要在小数的后面加F(大小写均可,建议大写)。因为浮点数的默认类型是double, double的取值范围是大于float的,类型不兼容。

2.7 数据类型转换

2.7-1 自动类型转换

public class Test {
    public static void main(String[] args) {
        int num = 10;
        double num2 = num;
        System.out.println(num2);
    }
}

转换过程由程序自动完成,程序会自动识别数据类型并完成 转换,但是这种操作对数据有要求:只能从低字节向高字节 进行转换,反之则不行。

同时浮点型数据可以对数据进行更加精准的描述,所以整型 数据类型都可以自动转为浮点型,此时不需要考虑低字节和 高字节的问题。

自动类型转换只包括数值类型,char 和 boolean 不能进行自 动类型转换。

2.7-2 强制类型转换

当两种数据类型不兼容,或目标类型的取值范围小于源类型时,自动转换将无法进行,这时就需要进行强制类型转换。

public class Test {
    public static void main(String[] args) {
        double num = 10.999;
        int num2 = (int)num;
        System.out.println(num2);
    }
}

结果为 10,只保留整数位,小数位全部舍弃,造成精度损失

2.8 算术运算符

2.8-1 基本算数运算符

包括:+、-、*、/、%、++、--

+、-、*、/、%这些运算符跟我们学的数学运算符是一样的。

符号作用说明
++自增变量的值加1
--自减变量的值减1

A++ 和 ++A 是有区别的,A++ 先使用 A 的值,再进行运算, ++A 先进行运算,再使用 A 的值。

2.8-2 复合算术运算符

基于基本算术运算符,进一步简化代码,包括:+=、-=、 *=、/=、%=

符号作用说明
=赋值a=10,将10赋值给变量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

2.8-3 关系运算符

关系运算符有6种关系,分别为小于、小于等于、大于、等于、大于等于、不等于。

符号说明
==a==b,判断a和b的值是否相等,成立为true,不成立为false
!=a!=b,判断a和b的值是否不相等,成立为true,不成立为false
a>b,判断a是否大于b,成立为true,不成立为false
>=a>=b,判断a是否大于等于b,成立为true,不成立为false
<a<b,判断a是否小于b,成立为true,不成立为false
<=a<=b,判断a是否小于等于b,成立为true,不成立为false

2.8-4 逻辑运算符

逻辑运算符把各个运算的关系表达式连接起来组成一个复杂的逻辑表达式,以判断程序中的表达式是否成立,判断的结果是 true 或 false。

符号作用说明
&逻辑与a&b,a和b都是true,结果为true,否则为false
逻辑或ab,a和b都是false,结果为false,否则为true
逻辑异或a^b,a和b结果不同为true,相同为false
!逻辑非!a,结果和a的结果正好相反
//定义变量
int i = 10;
int j = 20;
int k = 30;

//& “与”,并且的关系,只要表达式中有一个值为false,结果即为false
System.out.println((i > j) & (i > k)); //false & false,输出false
System.out.println((i < j) & (i > k)); //true & false,输出false
System.out.println((i > j) & (i < k)); //false & true,输出false
System.out.println((i < j) & (i < k)); //true & true,输出true
System.out.println("--------");

//| “或”,或者的关系,只要表达式中有一个值为true,结果即为true
System.out.println((i > j) | (i > k)); //false | false,输出false
System.out.println((i < j) | (i > k)); //true | false,输出true
System.out.println((i > j) | (i < k)); //false | true,输出true
System.out.println((i < j) | (i < k)); //true | true,输出true
System.out.println("--------");

//^ “异或”,相同为false,不同为true
System.out.println((i > j) ^ (i > k)); //false ^ false,输出false
System.out.println((i < j) ^ (i > k)); //true ^ false,输出true
System.out.println((i > j) ^ (i < k)); //false ^ true,输出true
System.out.println((i < j) ^ (i < k)); //true ^ true,输出false
System.out.println("--------");

//! “非”,取反
System.out.println((i > j)); //false
System.out.println(!(i > j)); //!false,,输出true

2.8-5 短路逻辑运算符

符号作用说明
&&短路与作用和&相同,但是有短路效果
短路或作用和相同,但是有短路效果

在逻辑与运算中,只要有一个表达式的值为false,那么结果就可以判定为false了,没有必要将所有表达式的值都计算出来,短路与操作就有这样的效果,可以提高效率。同理在逻辑或运算中,一旦发现值为true,右边的表达式将不再参与运算。

  • 逻辑与&,无论左边真假,右边都要执行。
  • 短路与&&,如果左边为真,右边执行;如果左边为假,右边不执行。
  • 逻辑或|,无论左边真假,右边都要执行。
  • 短路或||,如果左边为假,右边执行;如果左边为真,右边不执行。
int x = 3;
int y = 4;
System.out.println((x++ > 4) & (y++ > 5)); // 两个表达都会运算
System.out.println(x); // 4
System.out.println(y); // 5

System.out.println((x++ > 4) && (y++ > 5)); // 左边已经可以确定结果为false,右边不参与运算
System.out.println(x); // 4
System.out.println(y); // 4

2.8-6 条件运算符(三元运算符)

三元运算符语法格式:

关系表达式 ? 表达式1 : 表达式2;

解释:问号前面的位置是判断的条件,判断结果为boolean型,为true时调用表达式1,为false时调用表达式2。其逻辑为:如果条件表达式成立或者满足则执行表达式1,否则执行第二个。

举例:

int a = 10;
int b = 20;
int c = a > b ? a : b; // 判断 a>b 是否为真,如果为真取a的值,如果为假,取b的值

03-流程控制语句

3.1 流程控制语句分类

  • 顺序结构
  • 分支结构(if, switch)
  • 循环结构(for, while, do…while)

3.2 顺序结构

顺序结构是程序中最简单最基本的流程控制,没有特定的语法结构,按照代码的先后顺序,依次执行,程序中大多数的代码都是这样执行的。

顺序结构执行流程图:

3.3 分支结构之if语句

if语句格式有三种

//格式1:
if (关系表达式) { //首先计算关系表达式的值
    语句体;	     //如果关系表达式的值为true就执行语句体
}                //如果关系表达式的值为false就不执行语句体
    
//格式2:
if (关系表达式) { //首先计算关系表达式的值
    语句体1;	     //如果关系表达式的值为true就执行语句体1
} else {         
    语句体2;	     //如果关系表达式的值为false就执行语句体2
}

//格式3:
if (关系表达式1) {//首先计算关系表达式1的值
    语句体1;	     //如果值为true就执行语句体1;如果值为false就计算关系表达式2的值
} else if (关系表达式2) {
    语句体2;	     //如果值为true就执行语句体2;如果值为false就计算关系表达式3的值
} 
…
else {
    语句体n+1;   //如果没有任何关系表达式为true,就执行语句体n+1。
}

3.4 分支结构之switch语句

//格式
switch (表达式) {
	case 1:
		语句体1;
		break;
	case 2:
		语句体2;
		break;
	...
	default:
		语句体n+1;
		break;
}
  • 首先计算出表达式的值
  • 其次,和case依次比较,一旦有对应的值,就会执行相应的语句,在执行的过程中,遇到break就会结 束。
  • 最后,如果所有的case都和表达式的值不匹配,就会执行default语句体部分,然后程序结束掉。
  • 注意:如果switch中得case,没有对应break的话,则会出现case穿透的现象。

3.5 循环结构之for语句

  • 循环:循环语句可以在满足循环条件的情况下,反复执行某一段代码,这段被重复执行的代码被称为循环体语句,当反复 执行这个循环体时,需要在合适的时候把循环判断条件修改为false,从而结束循环,否则循环将一直执行下去,形 成死循环。
  • for循环格式:
for (初始化语句;条件判断语句;条件控制语句) {
	循环体语句;
}
  • 格式解释
    • 初始化语句: 用于表示循环开启时的起始状态,简单说就是循环开始的时候什么样
    • 条件判断语句:用于表示循环反复执行的条件,简单说就是判断循环是否能一直执行下去
    • 循环体语句: 用于表示循环反复执行的内容,简单说就是循环反复执行的事情
    • 条件控制语句:用于表示循环执行中每次变化的内容,简单说就是控制循环是否能执行下去
  • 执行流程
    1. 执行初始化语句
    2. 执行条件判断语句,看其结果是true还是false如果是false,循环结束如果是true,继续执行
    3. 执行循环体语句
    4. 执行条件控制语句⑤回到②继续

3.6 循环结构之while语句

while循环完整格式:

//初始化语句;
while (条件判断语句) {
	循环体语句;
    条件控制语句;
}

while循环执行流程

  1. 执行初始化语句
  2. 执行条件判断语句,看其结果是true还是false
    1. 如果是false,循环结束
    2. 如果是true,继续执行
  1. 执行循环体语句
  2. 执行条件控制语句
  3. 回到②继续

3.7 循环结构之do-while语句

完整格式:

//初始化语句;
do {
	循环体语句;
	条件控制语句;
}while(条件判断语句);

执行流程:

  1. 执行初始化语句
  2. 执行循环体语句
  3. 执行条件控制语句
  4. 执行条件判断语句,看其结果是true还是false
    1. 如果是false,循环结束
    2. 如果是true,继续执行
  1. 回到②继续

3.8 循环结构中 while、do-while、for 的区别


  • 1、for循环和while循环先判断条件是否成立,然后决定是否执行循环体(先判断后执行)
  • 2、do…while循环先执行一次循环体,然后判断条件是否成立,是否继续执行循环体(先执行后判断)
  • while 和 do-while 适用于循环次数不确定的场景。(do-while很少用到)
  • for 循环适用于循环次数确定的场景。

3.9 终止循环

break、continue的区别:

  • break 跳出整个循环体
  • continue 跳出本次循环,进入下一次循环

04-数组的应用

4.1 一维数组

数组就是一种可以存储大量数据类型相同的变量的数据结

构,具有相同数据类型的数据集合。

数组基本四要素

  • 数组名称
  • 数组元素
  • 元素下标
  • 数据类型
int[] array; //两种格式都可以表示一个数组
//int array[];

array = new int[3];//分配内存空间,指定数组长度,数组一旦创建,长度不能
修改。

array[0] = 50;//给数组赋值:通过下标找到数组中的位置,进行赋值。
array[1] = 60;
array[2] = 70;

//使用数组:通过下标取出数组中的具体数值。
System.out.print(array[0]);

数组的遍历:

int[] array;
array = new int[3];
array[0] = 50;
array[1] = 60;
array[2] = 70;
for (int i = 0; i < array.length; i++) {
    System.out.println(array[i]);
}

4.2 内存存储位置

基本数据类型的变量和值都存储在栈内存中。

数组属于引用类型的存储,变量保存在栈内存中,变量的值 保存在堆内存中,通过地址的引用进行关联。 引用类型:只要通过 new 关键字创建的变量都是引用类型。

区域名称作用
寄存器给CPU使用,和我们开发无关。
本地方法栈JVM在使用操作系统功能的时候使用,和我们开发无关。
方法区存储可以运行的class文件。
堆内存存储对象或者数组,new来创建的,都存储在堆内存。
方法栈方法运行时使用的内存,比如main方法运行,进入方法栈中执行。

4.3 动态初始化格式

数组动态初始化就是只给定数组的长度,由系统给出默认初始化值

//数据类型[] 数组名 = new 数据类型[数组长度];
int[] arr = new int[3];

4.4 静态初始化格式

在创建数组时,直接将元素确定

完整版格式

//数据类型[] 数组名 = new 数据类型[]{元素1,元素2,...};
int[] arr = new int[]{1,2,3};

简化版格式

//数据类型[] 数组名 = {元素1,元素2,...};
int[] arr = {1,2,3};

4.5 二维数组

在 Java 中二维数组被看作数组的数组,即二维数组为一个特殊的一维数组,其每个元素又是一个一维数组。 Java 并不直接支持二维数组,但是允许定义数组元素是一维数组的一维数组,以达到同样的效果。声明二维数组的语法如下:

type array[][];
type[][] array;

其中,type 表示二维数组的类型,array 表示数组名称,第一个中括号表示行,第二个中括号表示列。