Java SE
一、准备
1、环境搭建、JDK
-
查看版本
1
2
3javac –version
或者
java –version
2、Java程序
开发 Java 程序,需要三个步骤:编写代码,编译代码,运行代码
- 编译代码、运行代码
1 |
|
1 |
|
jdk11开始,可以直接运行
1 |
|
3、IDEA使用
-
项目结构
- project(项目、工程)
- module(模块)
- package(包)
- class(类)
-
IDEA 常用快捷键
快捷键 | 功能效果 |
---|---|
main/psvm、sout、… | 快速键入相关代码 |
Ctrl + D | 复制当前行数据到下一行 |
Ctrl + Y | 删除所在行,建议用Ctrl + X |
Ctrl + ALT + L | 格式化代码 |
ALT + SHIFT + ↑ , ALT + SHIFT + ↓ | 上下移动当前代码 |
Ctrl + / , Ctrl + Shift + / | 单行注释,多行注释 |
二、基础语法
1、注释
1 |
|
2、字面量
计算机是用来处理数据的,字面量就是告诉程序员:数据在程序中的书写格式
常用数据 | 生活中的写法 | 程序中的写法 | 说明 |
---|---|---|---|
整数 | 666,-88 | 666,-88 | 写法一致 |
小数 | 13.14,-5.21 | 13.14,-5.21 | 写法一致 |
字符 | A, 0, 我 | ‘A’,‘0’, ‘我’ | 程序中必须使用单引号,有且仅能一个字符 |
字符串 | 黑马程序员 | “HelloWorld”,“黑马程序员” | 程序中必须使用双引号,内容可有可无 |
布尔值 | 真、假 | true 、false | 只有两个值:true:代表真,false:代表假 |
空值 | 值是:null | 一个特殊的值,空值(后面会讲解作用,暂时不管) |
3、变量
变量就是内存中的一块区域,用来存储一个数据的,且存储的数据可以被替换
-
变量是什么,有什么作用?
-
内存中的一块区域。
-
用来存储一个数据的,且存储的数据可以被替换。
-
-
变量的格式
- 数据类型 变量名称 = 初始值;
-
变量的基本特点
-
变量中只能存一个值
-
变量中存的值是可以替换的
-
4、关键字
- Java语言自己用到的一些词,有特殊作用的,我们称之为关键字。
abstract | assert | boolean | break | byte |
---|---|---|---|---|
case | catch | char | class | const |
continue | default | do | double | else |
enum | extends | final | finally | float |
for | goto | if | implements | import |
instanceof | int | interface | long | native |
new | package | private | protected | public |
return | strictfp | short | static | super |
switch | synchronized | this | throw | throws |
transient | try | void | volatile | while |
5、标识符
标志符就是名字。我们写程序时会起一些名字,如类名、方法名、变量名,取名时要遵守一定的规则。
-
标识符的要求
- 基本要求:由数字、字母、下划线(_)和美元符($)等组成
- 强制要求:不能以数字开头、不能是关键字、区分大小写
-
命名指导规范
-
变量名称:满足标识符规则,建议全英文、有意义、首字母小写,满足“驼峰模式”,
例如:int studyNumber = 59。
-
类名称: 满足标识符规则,建议全英文、有意义、首字母大写,满足“驼峰模式”,
例如:HelloWorld.java。
-
6、数据类型
- 引用数据类型(除基本数据类型之外的,如String ,其他的后面学习)
- 基本数据类型:4大类8种
数据类型 | 关键字 | 取值范围 | 内存占用(字节数) |
---|---|---|---|
整数 | byte | -128~127 | 1 |
… | short | -32768~32767 | 2 |
… | int(默认) | -2147483648~2147483647 (10位数) | 4 |
… | long | -9223372036854775808 ~ 9223372036854775807 (19位数) | 8 |
浮点数 | float | 1.401298e-45到3.402823e+38 | 4 |
… | double(默认) | 4.9000000e-324 到1.797693e+308 | 8 |
字符 | char | 0-65535 | 2 |
布尔 | boolean | true,false | 1 |
- 随便写的整数、小数字面值默认什么类型?
23 ,默认是int类型 , 加上L/l就是long类型的数据了。
23.8,默认是double类型,加上F/f就是float类型了。
7、类型转换
-
自动类型转换
类型范围小的变量,可以直接赋值给类型范围大的变量。
注意事项:
-
表达式的最终结果类型由表达式中的最高类型决定。
-
在表达式中,byte、short、char 是直接转换成int类型参与运算的。
-
-
强制类型转换
可以强行将类型范围大的变量、数据赋值给类型范围小的变量。
-
数据类型 变量2 = (数据类型)变量1、数据
-
-
注意事项
-
强制类型转换可能造成数据(丢失)溢出;
-
浮点型强转成整型,直接丢掉小数部分,保留整数部分返回。
-
-
8、运算符
运算符:对字面量或者变量进行操作的符号。
(1)算数运算符
符号 | 作用 | 说明 |
---|---|---|
+ | 加 | 参考小学一年级 |
- | 减 | 参考小学一年级 |
* | 乘 | 参考小学二年级,与“×”相同 |
/ | 除 | 与“÷”相同,注意:在Java中两个整数相除结果还是整数。 |
% | 取余 | 获取的是两个数据做除法的余数 |
++ | 自增 | 变量自身的值加1 |
– | 自减 | 变量自身的值减1 |
“+”做连接符**
“+”符号与字符串运算的时候是用作连接符的,其结果依然是一个字符串
1 |
|
(2)赋值运算符
-
基本赋值运算符
int a = 10; // 先看“=”右边,把数据10赋值给左边的变量a存储
-
扩展赋值运算符
符号 作用 说明 += 加后赋值 a+=b 等价于 a = (a的数据类型)(a+b); 将a + b的值给a -= 减后赋值 a-=b 等价于 a = (a的数据类型)(a-b); 将a - b的值给a *= 乘后赋值 a*=b 等价于 a = (a的数据类型)(a*b); 将a ***** b的值给a /= 除后赋值 a/=b 等价于 a = (a的数据类型)(a/b); 将a / b的商给a %= 取余后赋值 a%=b 等价于 a = (a的数据类型)(a%b); 将a % b的商给a 注意:扩展的赋值运算符隐含了强制类型转换。
(3)关系运算符
是对数据进行条件判断的符号,最终会返回一个比较的布尔结果(false,true)
符号 | 说明 |
---|---|
== | 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 |
(4)逻辑运算符
可以把多个条件的布尔结果放在一起运算,最终返回一个布尔结果。
符号 | 介绍 | 说明 |
---|---|---|
& | 逻辑与 | 必须都是true,结果才是true; 只要有一个是false,结果一定是false。 |
| | 逻辑或 | 只要有一个为true、结果就是true |
! | 逻辑非 | 你真我假、你假我真。 !true=false 、 !false= true |
^ | 逻辑异或 | 如果两个条件都是false或者都是true则结果是false。两个条件不同结果是true。 |
短路逻辑运算符
符号 | 介绍 | 说明 |
---|---|---|
&& | 短路与 | 判断结果与“&”一样。过程是左边为 false,右边则不执行。 |
|| | 短路或 | 判断结果与“|”一样。过程是左边为 true, 右边则不执行。 |
注意:逻辑与 “&” 、逻辑或“|”;无论左边是 false还是true,右边都要执行。
(5)三元运算符
条件表达式 **?** 值1 **:** 值2;
执行流程:首先计算关系表达式的值,如果值为true,返回值1,如果为false,返回值2。
(6)运算符优先级
1 |
|
三、流程控制
1、分支结构
(1)if 分支
1 |
|
(2)switch 分支
1 |
|
注意事项:
-
表达式类型只能是byte、short、int、char,JDK5开始支持枚举,JDK7开始支持String、不支持double、float、long。
-
case给出的值不允许重复,且只能是字面量,不能是变量。
-
不要忘记写break,否则会出现穿透现象。
2、循环结构
(1)for 循环
- 格式:
1 |
|
- 举例
1 |
|
(2)while 循环
- 格式
1 |
|
- 举例
1 |
|
(3)do-while 循环
- 格式
1 |
|
- 举例
1 |
|
(4)死循环
1 |
|
3、跳转控制语句
- break : 跳出并结束当前所在循环的执行。
- continue: 用于跳出当前循环的当次执行,进入下一次循环。
注意事项
break : 只能用于结束所在循环, 或者结束所在switch分支的执行。
continue : 只能在循环中进行使用。
四、数组
1、数组的定义
(1)静态初始化
定义数组的时候直接给数组赋值。
-
完整格式
数据类型[] 数组名 = new 数据类型[]{元素1,元素2 ,元素3… };
1 |
|
-
简化格式
数据类型[] 数组名 = { 元素1,元素2 ,元素3,… };
1 |
|
注意:
- 数组变量名中存储的是数组在内存中的地址,数组是引用类型。
- 数组一旦定义出来,程序执行的过程中,长度、类型就固定了。
原理:
![](/static/imgs/loading.gif)
(2)动态初始化
定义数组的时候只确定元素的类型和数组的长度,之后再存入具体数据。
-
格式
数据类型[] 数组名 = new 数据类型[长度];
1 |
|
- 默认值
数据类型 | 明细 | 默认值 |
---|---|---|
基本类型 | byte、short、char、int、long | 0 |
… | float、double | 0.0 |
… | boolean | false |
引用类型 | 类、接口、数组、String | null |
**(3)**两种格式的写法是独立的,不可以混用。
int[] arrs = new int[3]{30,40,50};
是错误的
2、数组的访问
数组名称[索引]
1 |
|
- 数组的长度属性:length
1 |
|
表示数组的最大索引:数组名.length - 1 //前提:元素个数大于0
- 遍历
1 |
|
3、数组内存
4、常见问题
-
问题1:如果访问的元素位置超过最大索引,执行时会出现 ArrayIndexOutOfBoundsException (数组索引越界异常)
1
2
3int[] arr = new int[]{11, 22, 33};
System.out.println(arr[2]);
// System.out.println(arr[3]) // 出现异常 -
问题2:如果数组变量中没有存储数组的地址,而是null, 在访问数组信息时会出现 NullPointerException (空指针异常)
1
2
3arr = null;
System.out.println(arr); // null
System.out.println(arr.length) // 出现异常
五、方法
1、方法的定义与调用
(1)定义
格式
1 |
|
示例
1 |
|
方法不需要返回结果,则申明返回值类型为void;方法不需要参数,则形参列表可以不写。
return;
可以立即跳出并结束当前方法的执行。
(2)调用
格式
方法名(…);
示例
1 |
|
2、方法调用的内存图
方法是放在方法区中的,被调用的时候,需要进入到栈内存中运行
3、方法的参数传递机制
在传输实参给方法的形参的时候,并不是传输实参变量本身, 而是传输实参变量中存储的值,这就是值传递。
- 基本类型和引用类型的参数在传递的时候有什么不同?
- 都是值传递。
- 基本类型的参数传输存储的数据值。
- 引用类型的参数传输存储的地址值。
4、方法的重载
同一个类中,出现多个方法名称相同,但是形参列表是不同的,那么这些方法就是重载方法。
方法重载的判定
-
只要是同一个类中,方法名称相同、形参列表不同,那么他们就是重载的方法,其他都不管!(如:修饰符,返回值类型都无所谓)
-
形参列表不同指的是:形参的个数、类型、顺序不同,不关心形参的名称。
六、面向对象
面向对象的三大特征:封装,继承,多态。
l面向对象的四大特征:抽象,封装,继承,多态。
1、定义类
-
类名首字母建议大写,且有意义,满足“驼峰模式”。
-
一个Java文件中可以定义多个class类,但只能一个类是public修饰,而且public修饰的类名必须成为代码文件名。
-
实际开发中建议还是一个文件定义一个class类。
-
成员变量的完整定义格式是:
修饰符 数据类型 变量名称 = 初始化值;
, 一般无需指定初始化值,存在默认值。1
2
3
4
5
6
7
8
9
10
11public class Student {
// 属性 (成员变量)
String name;
double height;
// 行为(方法)
public void study(){
}
public void run(){
}
}
2、对象在内存中的运行机制(回B站看)
-
对象到底是放在哪个位置的?
堆内存中
-
Car c = new Car();
c变量名中存储的是什么?存储的是对象在堆内存中的地址。
-
成员变量
(name、price)
的数据放在哪里,存在于哪个位置?l对象中,存在于堆内存中。
垃圾回收
当堆内存中的对象,没有被任何变量引用(指向)时,就会被判定为内存中的**“垃圾”。**
3、构造器
定义在类中的,可以用于初始化一个类的对象,并返回对象的地址。
格式
1 |
|
示例
1 |
|
调用构造器得到对象的格式
1 |
|
示例
1 |
|
构造器的注意事项
-
任何类定义出来,默认就自带了无参数构造器,写不写都有。
-
一旦定义了有参数构造器,那么无参数构造器就没有了,如果还想用无参数构造器,此时就需要自己手写一个无参数构造器了。
4、this关键字
可以出现在构造器、方法中
代表当前对象的地址。
5、封装
封装:告诉我们,如何正确设计对象的属性和方法。
封装的原则:对象代表什么,就得封装对应的数据,并提供数据对应的行为。
如何进行封装更好?
- 一般建议对成员变量使用private(私有、隐藏)关键字修饰进(private修饰的成员只能在当前类中访问)。
- 为每个成员变量提供配套public修饰的的getter、setter方法暴露其取值和赋值。
6、JavaBean
也可以称为实体类,其对象可以用于在程序中封装数据
标准JavaBean须满足如下书写要求:
-
成员变量使用 private 修饰。
-
提供成员变量对应的 setXxx() / getXxx()方法。
-
必须提供一个无参构造器;有参数构造器是可写可不写的。
7、static关键字
static是静态的意思,可以用来修饰成员变量、成员方法。
static修饰成员变量之后称为静态成员变量(类变量),修饰方法之后称为静态方法(类方法)。
static修饰后的成员变量,可以被类的所有对象共享(访问、修改)。
- 静态成员变量内存图
-
静态成员变量(有static修饰,属于类、加载一次,内存中只有一份),访问格式
类名.静态成员变量
(推荐)对象.静态成员变量
(不推荐)
-
实例成员变量(无static修饰,属于对象),访问格式:
对象.实例成员变量
-
静态成员方法(有static修饰,归属于类),建议用类名访问,也可以用对象访问。
-
实例成员方法(无static修饰,归属于对象),只能用对象触发访问。
静态成员方法内存图
static访问注意事项:
-
静态方法只能访问静态的成员,不可以直接访问实例成员。
-
实例方法可以访问静态的成员,也可以访问实例成员。
-
静态方法中是不可以出现this关键字的。
工具类
类中都是一些静态方法,每个方法都是以完成一个共用的功能为目的,这个类用来给系统开发人员共同使用的。
一是调用方便,二是提高了代码复用(一次编写,处处可用)
为什么工具类中的方法不用实例方法做?
-
实例方法需要创建对象调用。
-
此时用对象只是为了调用方法,这样只会浪费内存。
ps: 由于工具里面都是静态方法,直接用类名即可访问,因此,工具类无需创建对象,建议将工具类的构造器进行私有。
代码块
代码块是类的5大成分之一(成员变量、构造器,方法,代码块,内部类),定义在类中方法外。
在Java类下,使用 { } 括起来的代码被称为代码块 。
代码块分为
-
静态代码块:
- 格式:static{}
- 特点:需要通过static关键字修饰,随着类的加载而加载,并且自动触发、只执行一次
- 使用场景:在类加载的时候做一些静态数据初始化的操作,以便后续使用。
-
构造代码块(了解,见的少):
- 格式:{}
- 特点:每次创建对象,调用构造器执行时,都会执行该代码块中的代码,并且在构造器执行前执行
- 使用场景:初始化实例资源。
如果要在启动系统时对静态资源进行初始化,则建议使用静态代码块完成数据的初始化操作。
单例模式
可以保证系统中,应用该模式的这个类永远只有一个实例,即一个类永远只能创建一个对象。
例如任务管理器对象我们只需要一个就可以解决问题了,这样可以节省内存空间。
-
饿汉单例设计模式
-
在用类获取对象的时候,对象已经提前为你创建好了。
-
定义一个类,把构造器私有。
-
定义一个静态变量存储一个对象。
-
/** a、定义一个单例类 */ public class SingleInstance { /** c.定义一个静态变量存储一个对象即可 :属于类,与类一起加载一次 */ public static SingleInstance instance = new SingleInstance (); /** b.单例必须私有构造器*/ private SingleInstance (){ System.out.println("创建了一个对象"); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
+ **懒汉单例设计模式**
+ > 在真正需要该对象的时候,才去创建一个对象(延迟加载对象)。
+ 定义一个类,把构造器私有。
+ 定义一个静态变量存储一个对象。
+ 提供一个返回单例对象的方法
+ ```java
/** 定义一个单例类 */
class SingleInstance{
/** 定义一个静态变量存储一个对象即可 :属于类,与类一起加载一次 */
public static SingleInstance instance ; // null
/** 单例必须私有构造器*/
private SingleInstance(){}
/** 必须提供一个方法返回一个单例对象 */
public static SingleInstance getInstance(){
if (instance == null) {
instance = new SingleInstance();
}
return instance;
}
}
-
8、继承
Java中提供一个关键字extends,用这个关键字,我们可以让一个类和另一个类建立起父子关系。
Student称为子类(派生类),People称为父类(基类 或超类)。
作用:当子类继承父类后,就可以直接使用父类公共的属性和方法了
好处:提高代码的复用性,减少代码冗余,增强类的功能扩展性
格式:
子类 extends 父类
七、String、ArrayList
1、String类
(1)概述
java.lang.String 类代表字符串,String类定义的变量可以用于指向字符串对象,然后操作该字符串。
Java 程序中的所有字符串文字(例如“abc”)都为此类的对象。
String类的特点详解
- String其实常被称为不可变字符串类型,它的对象在创建后不能被更改。
- String变量每次的修改其实都是产生并指向了新的字符串对象
字符串对象存在哪里?
- 在字符串常量池中存储。
(2)字符串的内容比较
字符串的内容比较 不适合 用“==”比较。(基本数据类型比较时使用)
1 |
|
推荐使用String类提供的“equals”比较:只关心内容一样即可
方法名 | 说明 |
---|---|
public boolean equals (Object anObject) | 将此字符串与指定对象进行比较。只关心字符内容是否一致! |
public boolean equalsIgnoreCase (String anotherString) | 将此字符串与指定对象进行比较,忽略大小写比较字符串。只关心字符内容是否一致! |
(3)String常用API
方法名 | 说明 |
---|---|
public int length() | 返回此字符串的长度 |
public char charAt(int index) | 获取某个索引位置处的字符 |
public char[] toCharArray() | 将当前字符串转换成字符数组返回 |
public String substring(int beginIndex, int endIndex) | 根据开始和结束索引进行截取,得到新的字符串(包前不包后) |
public String substring(int beginIndex) | 从传入的索引处截取,截取到末尾,得到新的字符串 |
public String replace(CharSequence target, CharSequence replacement) | 使用新值,将字符串中的旧值替换,得到新的字符串 |
public String[] split(String regex) | 根据传入的规则切割字符串,得到字符串数组返回 |
(4)创建字符串的两种方式
-
方式一:直接定义
String name = "ggw&xpl";
-
方式二:通过String构造类创建
构造器 说明 public String() 创建一个空白字符串对象,不含有任何内容 public String(String original) 根据传入的字符串内容,来创建字符串对象 public String(char[] chs) 根据字符数组的内容,来创建字符串对象 public String(byte[] chs) 根据字节数组的内容,来创建字符串对象
面试常考:
两种方式有什么区别
- 以“”方式给出的字符串对象,在字符串常量池中存储,而且相同内容只会在其中存储一份。
- 通过构造器new对象,每new一次都会产生一个新对象,放在堆内存中。
1 |
|
(5)String常见面试题
1 |
|
2、Arraylist
集合的特点
- 集合的大小不固定,启动后可以动态变化,类型也可以选择不固定
- 集合非常适合做元素个数不确定,且要进行增删操作的业务场景
- 集合还提供了许多丰富、好用的功能,而数组的功能很单一
- 集合中存储的元素并不是对象本身,而是对象的地址
ArrayList是集合中的一种,它支持索引
(1)对象创建
构造器 | 说明 |
---|---|
public ArrayList() | 创建一个空的集合对象 |
(2)增加元素
方法名 | 说明 |
---|---|
public boolean add(E e) | 将指定的元素追加到此集合的末尾 |
public void add(int index,E element) | 在此集合中的指定位置插入指定的元素 |
(3)泛型
ArrayList
:其实就是一个泛型类,可以在编译阶段约束集合对象只能操作某种数据类型。
例如:ArrayList<String>
:此集合只能操作字符串类型的元素。
注意:泛型只能支持引用数据类型,不支持基本数据类型。
(4)ArrayList集合常用方法
方法名称 | 说明 |
---|---|
public E get(int index) | 返回指定索引处的元素 |
public int size() | 返回集合中的元素的个数 |
public E remove(int index) | 删除指定索引处的元素,返回被删除的元素 |
public boolean remove(Object o) | 删除指定的元素,返回删除是否成功 |
public E set(int index,E element) | 修改指定索引处的元素,返回被修改的元素 |