1. 1995.5.23 sun推出的一款面向对象的编程语言。
2. Java的发展方向:JavaSE(Java的语言基础)、JavaME(通信方向)、JavaEE(企业级的应用)
1. 简单性(相对C c++等)
2. 面向对象性
3. 跨平台性(可以在不同的操作系统OS上运行)
1. Java的运行机制:先编译后解释运行
将源文件(.java)—>通过编译器生成对应的字节码文件(.class 二进制文件)
---->通过解释器逐行的解释并运行
2. 注意:体现Java的跨平台性的内容为字节码文件。
3. Java的运行特点:一次编译多次运行。(多次运行-》运行的.class文件)
1. JVM: Java虚拟机,作用屏蔽不同操作系统之间的差异性。
2. JRE: Java的运行环境(JRE= JVM+解释器)
3. JDK: Java的工具包(JDK= 编译器+JRE+类库+工具)
1. JAVA_HOME: JDK的根目录
2. Path: JDK的bin目录
3. ClassPath: 代表的是类路径,告知JVM所需要的类去哪找。
通常的内容为: . 代表在当前目录下查找所有需要的类。
注意:验证JDK的三个环境变量是否配置成功,在DOS命令窗口下输入
javac+回车 和 java + 回车
1. 源文件:以 .java 结尾
2. class 类名{ -->类是代码容器
//主函数:程序的入口,一个类中最多定义一个主函数
public static void main(String[] args){
System.out.println(“HelloWorld!”);//控制台输出,并且自动换行
System.out.print(“144班牛逼~”);//控制台输出,不自动换行
}
}
3.编译:javac 源文件名.java
4.运行: java 类名
注意:源文件中内容一旦更改,则需要重新编译,再次运行。
5. 注意:在一个源文件中可以定义多个类,但是类之间不能重名,
编译之后,每一个类会生成对应的 .class 文件。
6. public 的应用
① public 修饰符,公开的、公共的
② 被public修饰的类称为公开类、公共类
③ 注意:公开类的类名必须和源文件名完全一致;
一个源文件中最多定义有一个公开类。
1. 作用:类似于文件夹,方便文件管理。
2. 语法:package 包名1.包名2.包名3; ---->多层包结构
3. 注意:
① package 需要定义在源文件第一行有效语句
② 一个源文件中最多有一个package语句
4. 带包的编译和运行:
编译: javac -d . 源文件名.java
运行:java 包名.类名
1. 良好的格式习惯
① 层级之间要有缩进
② 一行只写一个语句
2. 良好的标识符命名习惯【重点】
① 硬性要求(语法要求):【面试+开发应用重点】
a. Java中的标识符只能以数字、字母、下划线(_)、$ 组成,但是不能以数字开头
b. Java中的标识符严格区分大小写
c. Java中的标识符没有长度限制
d. 不能以Java中关键字、保留字(goto/const)、特殊字符命名 (true/false/null)
注意:Java可以使用汉字作为标识符,但是不建议使用
② 软性要求(建议写法):
a. 望文生义
b. 类名每一个单词的首字母大写
c. 包名全小写
d. 常量名全部大写: PI
e. 变量名、函数名(方法名)首单词的首字母小写,其余单词的首字母大写(驼峰命名 法) 如:studentNameAndAge
3. 良好的注释习惯
① 单行注释: // 解释型的内容…
② 多行注释:/* 解释的内容…*/
注意:单行注释不可以嵌套多行注释,但是多行注释可以嵌套单行注释。
③ 文档注释 /**可以写多行的文档内容… */
javadoc -d dos 源文件名.java ---->生成对应的说明性文档
1. 概念:计算中一块内存空间,数据的基本存储单位。【理解】
2. 组成:数据类型、变量名、值(数据)。【理解】
3. 定义:【语法基础】
① 声明:数据类型 变量名;
② 初始化:变量名 = 值;
4. 其他定义方式:【语法基础】
① 声明的同时初始化:数据类型 变量名 = 值;
② 同时声明多个相同数据类型的变量:
数据类型 变量名1,变量名2=值,变量名3;
1. 基本数据类型(原始数据类型/简单数据类型)(8种)
① 整数类型
关键字
byte 1B -128~127
short 2B -32768~32767
int 4B -2147483648~2147483647
long 8B -922京~922京-1
注意:字节(Byte简称B) 1B = 8bites 位(bite简称为b)
字面值:定义中可以给变量赋的值。
long字面值后面需要加 L 或是 l,建议应用L(区分l 和 数字 1)
② 小数类型:
float 单精度 4B
double 双精度 8B
注意:
a. float字面值后面必须加 F 或是 f
b. double字面值后面可以加D 或是 d ,也可不加。
c. float和double都可以采用科学计数法的形式存储(底层是近似值存储)
面试题目:分析 int 类型的变量和float类型的变量哪一个存储数据更宽泛,说明原因。
③ 字符类型:
char 2B
字面值:
a. 用单引号引起来的一个字符 【重点】
char c = ‘A’;
char c2 = ‘中’;
b. 以整数的形式进行存储:(0~65535)【理解】
char c = 65;
char c2 = 29233;
c. 用 unicode形式存储:
char c = ’ u41’;
转义字符:
t : 水平跳格 n : 换行 : 反斜杠
’ : 单引号 " : 双引号
注意:以上的符号必须都是英文符号。
④ 布尔类型:
boolean 字面值 true/false
注意:Java的布尔类型和 0/1没有任何关系。
① 类、数组、接口、集合等都是引用类型。
② 以String(字符串) 为例:
a. 字面值:用双引号引起来的一个或是多个字符。
b. 案例: String s = “abcghgjhsjfysu”;
1. 数据类型的自动提升
① 当小数据类型的变量赋值给大数据类型的变量时,发生自动类型提升。
(从数据的存储范围来判定数据的大小类型)
② 规则:
a. byte->short -> int -> long -> float - > double
b. char -> int -> long -> float -> double
面试题目:
分析一下代码编译是否通过,不能说明原因。
char c = 65; 和 int i =65; char c2 = i
① 场景:当大数据类型的变量赋值小数据类型的变量时,需要使用强制类型转换。
② 语法:大数据类型 大数据类型的变量名= 值;
小数据类型 变量名 = (小数据类型)大数据类型的变量名;
③ 强制转换的结果
a. 小数据类型强转为整数类型,则直接截取整数部分
double d = 12.7;
int i =(int)d;
b. 大数据类型的整数变量给小数据类型的整数变量赋值,
给的数据合理,则不损失任何内容
int i = 12;
byte b = (byte)i;
c. 大数据类型的整数变量给小数据类型的整数变量赋值,
给的数据不合理,将字节截取
int i = 257;
byte b=(byte)i; —> 打印输出结果1
1. 概念:由变量、字面值、运算符等组成一个式子,通常会产生一个结果。【理解】
2. 当两个数值或是变量参与运算时,如果参与运算的两个变量或是数据类型不一致,
运算过程中,会发生类型转换,转换规律如下:【理解+应用重点】
① 有double结果类型为 double;
② 没有double前提下,有float,结果类型为 float;
③ 没有double/float,有long,结果类型为long;
④ 其余的情况全部为 int 。
面试题目:
分析以下代码编译是否通过,通过写出结果,否则说明原因。
byte b = 1;
b = b + 1;
System.out.println(b);
1. 算术运算符
+ - *(乘) /(除) %(取模/取余数)
注意:
① +两端如果为字符串类型的数据,则+为字符串的连接符。–》字符的拼接
② 如果+两端有一个是字符串的数据,则结果自动提升为字符串类型
2. 赋值运算符:= += -= *= /= %=
注意:+= 没有自动类型提升。
面试题目:
分析以下代码编译是否通过,通过写出结果,否则说明原因。
① byte b = 1;
b = b + 1;
System.out.println(b);//编译报错
② byte a= 1;
a+=1;
System.out.println(a); //编译通过,原因:+=没有自动类型提升,打印结果为2
3. 关系运算符
> 大于
>= 大于等于
< 小于
<= 小于等于
== 等于
!= 不等于
表达式的结果类型为布尔类型,这样的表达式称为布尔表达式。
注意:用关系运算符连接的表达式都为布尔表达式,
关系成立-true;关系不成立结果为false.
4. ++(自增) --(自减) —》一元运算符
面试题目:
a++: 先使用a变量原有的数据,然后再将a的内容加1(先使用,再加1)
++a: 先将a的内容加1,再使用 a的数据(先加1,再使用)
int c = a++ + (–a) +(a++);
System.out.println(a);
System.out.println©;
5. 逻辑运算符【基础应用】
① && :逻辑与,两个条件都为 true,则结果才为true.(短路运算符)
② || :逻辑或,两个条件有一个true,结果就为true.(短路运算符)
③ & :逻辑与,两个调价都为 true,则结果为true.(非短路运算符)
④ | : 逻辑或,两个条件只要有一个 true,结果为true.(非短路运算符)
⑤ ! :逻辑非,对结果取反。
6. 条件运算符(三元运算符)[了解]
① 语法:布尔表达式 ? 表达式1: 表达式2;
② 原理:如果布尔表达式的结果为true,则执行表达式1,否则执行表达式2.
1. 应用:java.util.Scanner sc = new java.util.Scanner(System.in);
2. 使用:
① 输入一个整数:int a = sc.nextInt();
② 输入一个小数:double d = sc.nextDouble();
③ 输入一个字符串:String str = sc.next(); // String str sc.nextLine();
④ 输入一个布尔内容:boolean b = sc.nextBoolean();
⑤ 输入一个字符: char c = sc.next().charAt(0);
1. 语法:import 包名1.包名2.类名; //导入包中一个类
import 包名1.包名2.*; //导入包中的所有的类
2. 位置:定义在package 的语句后面
3. 注意:
① 一个源文件中可以有多个import语句;
② java.lang包中的内容自动导入,无需导包。
1. if基本结构
① 语法:
if(布尔表达式/条件){
//语句
}
执行原理:如果布尔表达式的结果为true 则执行{}中的语句。
② 语法:
if(布尔表达式){
//语句1
}else{
//语句2
}
执行原理:如果布尔表达式的结果为true,则执行语句1, 否则执行语句2.
2. 多重的if结构
① 语法:
if(布尔表达式){
//语句1
}else if(布尔表达式){
//语句2
}else if(布尔表达式){
//语句3
}else{
//语句4…
}
② 执行原理:哪一个布尔表达式成立,则执行对应{}中的语句。
3. 嵌套的if结构
① 语法:
if(布尔表达式){
if(布尔表达式){
//语句…
}else{
//…
}
}else{
}
② 执行原理:先判断外层条件,外层条件成立(布尔表达式为true),
则再去判断内层条件。
1. 语法:
switch(表达式){
case 值1: 语句1;break;
case 值2: 语句2;break;
case 值3: 语句3;break;
default: 语句n;break;
}
2. 执行的原理:将表达式的结果和case后面的值从上往下依次匹配,哪一个相等,则执行 case后面对应的语句,如果都不相等,则执行default后面的语句。
3. 注意:
① switch后面表达式的结果类型必须是:byte、short、int、char;
JDK7.0版本之后,支持String类型的结果。
② switch…case结构本身没有终止自身结构的能力,需要在语句的后面
添加break语句,用于终止switch…case结构。
③ default没有位置要求,所有后面的break建议不要省略;
switch…case结构中可以没有default语句。
④ case后面的值不允许重复
1. 概念:定义在函数内部的变量。
2. 特点:
① 局部变量必须先赋值后使用。
② 作用范围:从定义位置开始,到定义它的代码块结束。
③ 命名冲突:在重合的作用范围内,不允许命名冲突(不允许有重名的局部变量)
1. 概念:通过某一个条件,重复并且有规律的执行一段程序代码。
2. 组成:循环变量的初始化、循环条件、循环变量的改变(递增/递减)、循环体
3. 循环的分类:
① while循环【开发应用重点】
a. while(循环条件/布尔表达式){
//循环体…
}
b. 执行的原理:先判断循环条件是否满足(布尔表达式是为true),如果条件满足则执 行循环体的内容,并且改变循环变量的内容,再次判断条件是否满足,满足继 续执行循环体,同时改变循环变量…直到条件不满足(布尔表达式的结果为false) 为止,跳出循环结构。
c. 执行特点:先判断,再执行,执行次数:0~n次。
d. 注意:开发时,避免出现死循环的现象。
② do…while循环
a. 语法:
do{
//循环体…
}while(循环条件); //注意:此处的分号不能省略
b. 执行原理:先执行循环体,再去判断循环条件,条件成立则继续执行循环体的内 容,直到循环条件不满足为止,跳出循环。
c. 执行的特点:先执行,再判断,执行次数1~n次。
③ for循环【开发应用重点】
a. 语法:
for(循环变量的初始化;循环条件;循环变量的改变){
//循环体…
}
b. 执行的原理:先进行循环变量的初始化,然后判断循环条件,条件成立则执行循 环体,从而循环变量改变;继续判断循环条件…直到循环条件不满 足为止,则跳出循环。
c. 执行特点:先判断,再执行,执行次数:0~n次。
总结:
1. 循环次数确定时,建议使用 for
2. 循环次数不确定时,建议使用 while
1. break: 终止、结束循环。
2. continue: 跳出、结束本次的循环,从而进入下一次循环。
面试重点:写出 break和 continue.
① break 跳出、终止循环;continue跳出、结束本次循环
② break可以应用于switch…case结构;但是continue不能应用此结构中
1. 概念:在一个循环结构中,定义了另一个循环结构。
2. 循环的次数:外层循环循环的次数*内层循环循环的次数。
3. 图形:通常情况用外层循环控制图形行数,用内层循环控制图形列数。
注意:有些情况下,内层循环会受外层循环的控制。
4. 循环的控制语句:
break:跳出、结束本层循环。
continue:结束本层的本次循环,从而进入本层下一次循环。
5. 循环的Lable标签:对循环做标记,可以通过标记对循环进行操作。[了解]
1. 概念:实现特定功能的代码组成的一个整体;可以通过名字反复使用。
2. 函数的应用流程:
① 函数的定义:确定函数的功能及函数名。
函数的声明:对函数起名并且声明此函数的功能。
函数的实现:如何实现函数对应的功能。
② 函数的使用:通过函数名使用函数的功能称为函数的调用。
3. 位置:定义在类以内,与main函数并列的位置(其他函数的外面)。
1. 语法:public static 返回值类型 函数名(形参列表){
//函数的实现…
}
2. 函数的定义分为:
① 函数的声明:public static 函数的返回值 函数名(形式参数列表)
I. 函数名:望文生义,建议使用驼峰命名法(首单词的首字母小写,其他单词的首字 母 大写)
II. 形式参数:用于约定函数和使用者之间的交互数据类型
a. 语法:(数据类型 参数名,数据类型2 参数名2,数据类型3 参数名3)
b. 应用:形式参数相当于函数内部的局部变量,在函数的内容直接利用参数名 直接使用即可。
c. 形参列表:参数的个数 0~n
III. 函数的返回值:
a. 无返回值类型:返回值类型为void,代表函数没有任何返回值, 即函数没有 return语句。(也可以利用 return;结束当前函数)
b. 有返回值类型:返回值类型为 8种基本数据类型 和 对象数据类型,代表函 数必须有 return XXX;语句
return的细节:
① 函数最多只能定义一个return XXX;语句
② return应用分支结构时,必须保证每一条分支都有return语句return 的作用:
① 将函数的返回值返回
② 结束当前函数的调用
注意:函数的返回值、函数名、形参列表称为函数的三要素。
② 函数的实现:{}
1. 函数的调用:函数名();//可以通过函数名反复的使用该函数 --》无参数的调用
2. 有参数的调用:函数名(实际参数列表);
① 实际参数的作用:在函数调用时,给形参赋值.
② 注意:实际参数的个数、顺序、数据类型必须和形参一致。
3. 有返回值的函数的调用:
数据类型 变量名 = 函数名(实际参数);
注意:数据类型决定于函数的返回值类型;
变量的作用是存储函数的返回值。
1. 减少代码的冗余
2. 提高的复用性
3. 提高的可维护性
1.概念:被调用的函数内部又调用了其他函数。
2.函数调用执行的流程:调用函数时,程序会先执行被调函数内部的代码, 被调函数全部 执行完如果有返回值,则带着返回值返回到调用位置,程序继续往下执行。
1. 概念: 在一个函数的内部调用它自身。
2. 注意:开发时,避免无穷递归的现象;需要给递归设置出口。
1. 概念:可以同时存储多个相同类型的数据,并可以对数组中的数据进行统一操作。
2. 数组的要素:数据类型、长度
3. 使用数组的基本流程:【重点】
① 声明:指定数组的数据类型及数组名;
语法: 数据类型[] 数组名;
例如: int[] a; //建议写法、int []a;、int a[];
② 分配空间:指定数组的长度
数组名 = new 数据类型[长度];
③ 使用数组:
a. 数组的下标:0~长度-1 (0~length-1)
b. 数组中存储的数据称为数组的元素。
c. 操作数组中元素利用数组名+下标:数组名[下标];
d. 如果操作数组过程中,下标超出数组的有效下标范围,则
编译通过,运行报错,错误信息如下:
**java.lang.ArrayIndexOutOfBoundsException(**下标越界)
e. 数组的遍历:将数组中的元素进行一一访问的过程。
for(int i=0;i<数组长度;i++){
//利用 i控制数组的下标,从而操作数组中的元素
}
注意:获取数组的长度–>数组名.length
f. 数组具有默认值,默认值情况如下:
整数类型: 0
小数类型: 0.0
字符类型:空字符(’ u0000’)
布尔类型:false
引用类型:null
4. 数组的其他定义方式:
① 声明的同时分配空间【重点】:
数据类型[] 数组名 = new 数据类型[长度];
② 显示初始化:
数据类型[] 数组名 = new 数据类型[]{值1,值2,值3};
注意:[]中不允许指定长度,数组的长度由{}中数值的个数决定。
③ 显示初始化: 【重点】
数据类型[] 数组名 = {值1,值2,值3};
注意:数组的初始化和声明必须一起进行,{}中数据的个数决定了数组的长度。
1. 数组在内存空间中连续的,数组的空间分配好之后,会获得当前数组的首地址。
2. 数组名中存储数组在内存空间的首地址。
3. 寻址的公式:
首地址+下标*数据类型的字节数
注意:数组的下标从0开始,为了寻址方便。
4. 数组类型的变量之间相互赋值传递的是数组的首地址。
1.思想:
① 申请一个更大长度的新数组(长度一般为原始数组的长度2倍)
② 将原有数组的元素一一赋值到新数组中
③ 新地址覆盖旧地址
2. 实现方式:
int[] a={1,2,7};
① 申请更大长度的数组
int[] b = new int[a.length*2];
将原有数组的内容赋值到新数组中
for(int i=0;i b[i]=a[i]; } 新地址覆盖旧地址 a=b; ② 利用System.arraycopy(a,0,b,0,a.length)工具实现数组的赋值 参数说明: a. 第一个参数:原始数组名 b. 第二个参数:赋值起始下标,通常情况下取0 c. 第三个参数:新的数组名 d. 第四个参数:新数组存储的起始下标 e. 第五个参数:赋值的长度 ③ 利用 java.util.Arrays.copyOf(a,a.length*2)工具实现数组扩容的两个步骤。 参数说明: a. 第一个参数:原始数组的名 b. 第二个参数:新数组的长度 注意:当数组的长度不够用时,才需要考虑扩容。 1. 概念:使用函数时,可以给定个数不固定的实参,根据调用者自身决定参数的个数。 (JDK5.0提出.) 2. 语法: public static 返回值类型 函数名(数据类型…变量名){ //函数体(函数的实现) } 3. 使用:函数内部使用可变长参数时,将其作为数组使用即可。 4. 注意:一个函数中最多只能定义一个可变长的参数,并且要求可变长的参数必须形式参 数的最后一个。 5. 好处:让函数的调用更加的灵活。 1. 冒泡法:相邻的两个元素进行一一比较,最大的元素逐渐往后移。 //外层循环控制比较的轮数 for(int i=1;i //内层循环:控制每一轮具体比较的内容 for(int j=0;j if(a[j]>a[j+1]){ int t = a[j]; a[j]= a[j+1]; a[j+1]=t; } } } 2. 选择法:固定一个下标位置元素,和后面的元素进行一一比较,小的元素逐渐往前移。 //外层循环控制比较的轮数 for(int i=0;i //内层循环控制每一轮比较内容 for(int j=i+1;j if(a[i]>a[j]){ int t= a[i]; a[i]=a[j]; a[j]=t; } } } 3. 快速排序:java.util.Arrays.sort(数组名); 1. 定义: ① 声明:数据类型[][] 数组名; 分配空间:数组名 = new 数据类型[行数/高维][列数/低维]; ② 访问二维数组通过行标和列标: 数组名[行下标][列下标] 注意:行标和列标都是从0开始。 a[0][3]代表:第0行第3列的数据 ③ 二维数组同一维数组具有默认值。 ④ 获取二维数组的行数:数组名.length 获取二维数组的列数:数组名[0].length ⑤ 二维数组就是一维数组的一维数组。 2. 其他的定义方式: ① 声明同时分配空间: 数据类型[][] 数组名= new 数据类型[行数][列数]; ② 显示初始化: 数据类型[][] 数组名= new 数据类型[][]{{值1,值2},{值3,值4},{值5,值6}}; 注意:[][]中不能指定二维数组的行数和列数。 ③ 显示初始化: 数据类型[][] 数组名={{值1,值2,值3},{值4,值5,值6}}; 注意:初始化和声明必须一起进行。 3. 不规则的二维数组 ① 概念:每一行的列数不相同的二维数组。 ② 语法: a. int[][] a= {{1,2},{2,6,8}}; b. int[][] a = new int[3][]; a[0] = new int[2]; a[1] = new int[5]; a[2] = new int[3]; 注意:此种获取不规则二维数组的方式,必须指定行数(高维)。 1. 概念:客观复杂的事物在Java程序中的一种表象形式。(一切客观事物皆是对象) 2. 对象的组成: ① 对象的属性:代表对象有什么的特征(体现对象的静态部分-变量展现) ② 对象的方法:代表对象有什么样功能(体现对象的动态部分-方法展现) 3. 计算机中,用类描述对象,描述对象有哪些属性和哪些方法。 4. 类对象的关系: ① 类是对象的模板 ② 对象是类的实例(对象根据类创造) 1. 属性:代表对象有什么特征 ① 属性又称为成员变量 ② 位置:定义在类以内,方法以外 ③ 语法:数据类型 属性名; 数据类型 属性名 = 值; 注意:赋值和声明必须同时进行。 ④ 注意:定义属性时,只需保留程序所关注的部分。 ⑤ 成员变量具有默认值,默认值同数组: 整数:0 小数:0.0 布尔:false 字符:空字符( u0000) 引用/对象:null ⑥ 成员变量的作用范围:至少在本类中有效。(本类的成员方法可以直接利用成员变量 的名字直接使用) ⑦ 在一个类中,不允许有相同名字的成员变量(属性名); 成员变量可以和局部变量命名相同,命名相同时,在此局部变量所在方法中访问同 名变量时,局部变量优先使用。 总结:成员变量和局部变量的区别?【面试+开发应用重点】 局部变量 成员变量 位置: 定义在方法内部 定义在类以内,方法以外 默认值: 没有默认值(先赋值后使用) 具有默认值 作用范围:从定义位置开始,到定义它 至少本类中有效 的代码块结束 命名冲突:在重合的作用范围内,不允许 成员变量可以和局部变量命名相同,命 命名冲突 名相同时,在此局部变量所在方法中使 用此变量时,局部变量优先 2. 方法:代表对象有什么功能、行为 ① 方法称为成员方法。 ② 位置:定义在类以内,其他方法以外。 ③ 定义: 函数的定义: public static 返回值类型 函数名(形参列标){ //函数的实现(函数体) } 方法的定义: public 返回值类型 方法名(形参列表){ //方法的实现(方法体) } 注意:方法定义中,不需要加static. ④ 方法的定义分为 方法的声明和方法实现: a. 方法声明:代表对象能做什么 I. 修饰符 返回值类型 方法名(形参列表)异常 II.一个方法可以有多个修饰符,而且没有位置先后之分 b. 方法实现:代表对象如何做—》 { //方法的具体实现} ⑤ 方法的重载(overLoad) a. 概念:在一个类中,定义多个名字相同,但是参数列表不同的方法。 b. 要求: I. 方法名相同 II. 参数列表不同(类型、个数、顺序) III. 修饰符、返回值类型、异常没有要求 c. 注意:如果只是形参名不一样,则不能构成方法重载。 d. 使用:编译器在编译的过程中,根据调用者给定实际参数,决定具体调用哪一 个方法。 注意:使用过程中,根据调用者传递的实际参数先进行精确匹配,然后就近向上 匹配,避免出现混淆。 3. 构造方法(构造器 Constructor) ① 位置:定义类以内,其他方法以外 ② 特点: a. 构造方法的方法名必须和类名完全一致(包含大小写) b. 构造方法没有返回值类型 (连void都没有) 语法:修饰符 类名(形参列表){} c. 构造方法允许重载 d. 构造方法不允许手动调用 ③ 作用: a. 构造方法用于创建对象 b. 通常给属性赋值 ④ 注意: a. 构造方法不允许手动的调用,用于创建对象时,JVM自动调用1次 b. 如果一个类中没有定义任何的构造方法,则JVM会自动添加一个默认公开、 无参数的构造方法;如果一个类中定义了任何的构造方法,则系统JVM不再提 供默认公开、无参数的构造方法 1. 语法:类名 对象名 = new 构造方法(实参); 2. 使用对象: ① 属性: a. 为属性赋值:对象名.属性名 = 值; b. 访问属性:对象名.属性名 ② 方法:对象名.方法名(实参); 1. 分配空间:给所有的属性赋默认值 2. 初始化属性:给属性第二次赋值的机会 3. 调用构造方法:给属性第三次赋值的机会 1. 第一种应用:this. ① this 代表当前对象,类似于"我",this. 用在类中的成员方法或是构造方法中,调用 当前对象的属性或是成员方法 ② this.属性名:代表调用当前对象的属性 this.方法名(实参):代表调用当前对象的成员方法 ③ this. 通常可以省略,但是当成员变量和局部变量命名冲突时,必须使用 this. 区分 成员变量 2. 第二种应用:this() ① this():用在本类的构造方法中,调用本类其他构造方法。 ② this():代表调用无参数的构造方法 this(实参):调用有参数的构造方法 ③ this()的应用必须是构造方法中第一行有效语句 ④ 注意:使用 this()/this(实参)时,避免递归调用(回环调用)现象 1. 引用:对象类型的变量。 2. 引用存储对象在堆空间中的首地址。 3. 不同的对象在堆空间相互独立。 4. 引用可以单独声明: 类名 引用名; 5. 引用之间可以相互赋值,传递的是对象在堆空间中的首地址。基本数据类型的变量之间 传递的是数值。 6. 声明引用时,通常给定一个初始数据null(代表空地址) 类名 引用名 = null; 注意:如果引用中存储的为null,用此引用调用属性或是成员方法,则编译通过,但是 运行报错,错误信息为: **java.lang.NullPointerException(**空指针异常) 1. private:访问修饰符,私有的,被private修饰的内容只能在本类中使用。 2. 为私有化的属性提供公开的get/set方法: ① 为属性赋值(修改属性值):set方法 public void set属性名(数据类型 变量名){ this.属性名 = 变量名; } 注意: a. set属性名–》属性名首字母大写 b. ()中数据类型取决于赋值的属性类型 ② 获取属性的值:get方法 public 数据类型 get属性名(){ return this.属性名; } 注意: a. 返回值的数据类型取决于 获取的属性数据类型 b. get属性名 --》属性名首字母大写 3. 使用: ① 为属性赋值:对象名.set属性名(实参); ② 获取属性值:对象名.get属性名() 1. 概念:【理解】 ① 继承体现的是类之间一种 "is-a"关系 语法:class 子类类名 extends 父类类名{} ② 继承是一种机制,通过继承机制可以让子类直接使用父类中属性和方法 ③ 开发时,不能强制使用继承机制,继承是两个类本身存在一种"is-a"关系,不能人为、 刻意的使用。 2. 继承的好处:体现代码的可复用性和可扩展性。【理解】 3. 方法的覆盖(override)[重写->将方法的实现部分重写]【应用开发重点】 ① 概念:子类中定义了和父类相同的方法。 ② 要求: a. 子类的方法名、形参列表、返回值类型和父类相同 b. 子类的访问修饰符和父类相同或是比父类更宽 ③ 使用:子类对象名.方法名(实参);//子类中的方法优先使用 ④ 注意: a. 子类中定义方法和父类中的一个方法,方法名、形参列表相同,但是返回值类 型不同,编译报错。 b. 子类中定义的方法和父类中的一个方法,方法名、返回值类型相同,但是形参 列表不同,编译通过,运行也OK.—>特殊的方法重载 ⑤ 应用场景:当父类提供的方法实现部分不足以满足子类需求时,子类可以覆盖父类 中的方法(根据自身功能,重新将方法实现部分写一遍) 面试题目:分别写出overload和override的区别。 4. 将子类的共性抽取为父类中属性和方法。【理解】 父类中的信息是 一般的、抽象的 子类中的信息是 特殊的、具体的 5. Java中继承特点【面试重点】:Java中的类是单继承关系,即一个类只能有一个直接的 父类,但是可以有多个间接地父类(多级继承)–>体现Java语言的简单性 6. 子类可以继承父类中的哪些内容(构造方法、属性、成员方法)?【重点】 ① 构造方法不允许被子类继承【面试题目】 a. 语法角度:构造方法的方法名必须和类名一致,子类和父类各有不同的类名 b. 应用角度:子类中的内容多于父类中的内容,所有子类的构造内容比父类复杂, 所以子类需要定义自身的构造方法。 ② 属性和成员方法取决于访问修饰符(约束访问权限)【面试重点+应用重点】 本类 同包 不同包的子类 其他(不同的包非子类) private(私有的) ok default(默认的) ok ok protected(受保护的) ok ok ok public (公开的) ok ok ok ok ***属性和成员方法的继承性如下: private:不允许被继承 default:同包中的子类允许继承 protected:同包+不同的包的子类都允许继承 public:允许继承 访问修饰符可以修饰的内容: a. 4个访问修饰符都可以修饰属性、成员方法、构造方法 b. 只有public和 defaule可以修饰类 7. 创建对象的过程(继承体系下)【理解】 ① 分配空间(本类+父类):为所有的属性赋默认值 ② 递归的构造父类对象: a. 初始化父类的属性:为属性赋值的第二次机会 b. 调用父类的构造方法:为属性赋值的第三次机会 ③ 初始化本类的属性:为本类的属性赋值的第二次机会 ④ 调用本类(子类)的构造方法:为本类的属性赋值的第三次机会 8. super的应用【开发应用重点】 ① 第一种应用:super() a. super()/super(实参):用在子类的构造方法中,代表创建子类对象时,JVM需 要先完成父类对象的创建,指示JVM利用父类的哪一个构造方法完成父类对象 的创建。 b. 注意: I.super()/super(实参)必须是构造方法的第一行有效语句; II. 如果子类的构造方法的第一行没有定义super()/super(实参),则JVM默认在构 造方法的第一行添加super();语句 III. 一个构造方法中不能同时使用super()/super(实参) 和 this()/this(实参) IV. 如果子类的构造方法的第一行语句为this()/this(实参),则JVM会放弃在当前 构造方法中查找super()/super(实参),从而转向this所指向构造方法中的第一 行查找super()/super(实参) ② 第二种应用:super. a. super. :应用在子类的构造方法或是成员方法中,代表调用父类中属性或是成 员方法 b. super.属性名:访问父类的属性 super.方法名(实参):访问父类的成员方法 1. 概念【理解+基础重点+开发】 ① 多态:父类型的引用 指向 子类的对象。 父类型 引用名 = new 子类类名(实参); ② 如果用父类型的引用调用属性和方法,只能调用父类中声明的属性和方法; —>编译 时检测 ③ 运行时,JVM自动检测子类是否覆盖父类中方法,如果子类覆盖了父类中方法,则 运行覆盖之后的方法,否则直接运行父类中方法。 2. 引用之间的转换【应用重点】 ① 父类型的引用 赋值给 子类型的引用 必须 通过强制类型转换 子类型 引用名 = (子类型)父类型的引用; 注意:不管父类型引用中存储是哪一种子类型的对象,编译通过;但是运行时将 父类型的引用中实际存储的对象和转换的类型相比较,如果类型匹配,运 行通过;不匹配运行报错,错误信息为: **java.lang.ClassCastException(**类型转换异常) instanceof 的应用: I. 语法: 引用名 instanceof 类名 II.作用:判断引用中存储对象类型是否兼容于 后面的类型,兼容-true;不兼容 -false. III. 场景:引用之间转换时可以先利用instanceof进行判断,从而避免 类型转 换异常。 ② 子类型的引用 赋值给 父类型的引用 直接赋值 (多态的应用) 案例:Dog d = new Dog(); Animal a = d; ③ 转换双方没有继承关系,则不允许相互转换(编译报错) Animal a = new Dog(); Person p = (Person)a;//编译报错 3. 多态的应用【理解+开发应用重点】 ① 多态应用在数组上:本类型+所有子类型的对象都可以作为数组元素存储 ② 多态应用在形式参数上:本类型+所有的子类型都可以作为实际参数进行传递 ③ 多态应用在返回值上:本类型+所有的子类型都可以作为返回值返回。 4. 多态的好处:屏蔽不同子类之间的差异性,从而可以对不同子类进行统一操作。【理解】 1. abstract修饰类 ① 被abstract修饰的类称为抽象类 语法:abstract class 类名{} ② 抽象类不能单独创建对象,但是可以声明引用 ③ 抽象类中可以定义属性和成员方法 ④ 抽象类中有构造方法,但是构造方法是供子类创建对象时先完成父类对象的创建, 应用的。 2. abstract修饰方法 ① 被abstract修饰的方法称为抽象方法。 ② 抽象方法只有方法的声明部分,没有实现部分(连{}都没有) 语法:访问修饰符 abstract 返回值类型 方法名(形参); 注意:访问修饰符 和 abstract没有位置先后之分。 ③ 注意:抽象方法只能定义在抽象类中;抽象类中可以定义抽象方法和非抽象方法。 ④ 子类继承抽象类,如果子类不想成为抽象,则需要覆盖父类中所有的抽象方法,否 则子类也必须定义为抽象类。 3. 抽象类的作用:强制使用多态。 1. static 修饰属性 ① 被static修饰的属性称为静态属性、类变量、静态变量 ② 位置:定义在类以内,方法以外,被static修饰 ③ 语法:访问修饰符 static 数据类型 属性名; 注意:访问修饰符 和 static没有位置先后之分 ④ 静态属性的特点:类变量,和创建多少对象无关,全类共有。 ⑤ 使用:类名.静态属性名 2. static 修饰方法 ① 被static修饰的方法称为静态方法。 ② 位置:定义在类以内,其他方法以外,被 static修饰 ③ 语法:访问修饰符 static 返回值类型 方法名(形参){} ④ 使用:类名.静态方法名(实参); //建议使用 引用名.静态方法名(实参); ⑤ 注意: a. 静态方法中不能直接访问非静态的成员(非静态属性+成员方法) b. 静态方法中可以直接方法静态的成员(静态属性+方法) c. 静态方法中不能使用this/super 关键字 d. 静态方法能被子类继承 e. 静态方法只能被静态方法覆盖,而且没有多态的应用 思考:System.out.println();实现的原理?????【面试题目】 类 静态变量 静态方法 解析:System是类名 out是静态属性,类型是对象类型 println():是一个方法,是out对应的类型中的方法 3. static修饰初始化代码块 ① 初始化代码块(动态代码块):【了解】 a. 位置:定义在类以内,方法以外 {} b. 作用:创建对象时,按照和属性定义的先后顺序,完成对属性的初始化工作(在 创建对象的第二个过程初始化属性时执行). ② 被 static 修饰的初始化代码块称为静态初始化代码块【开发应用重点】 a. 位置:定义在类以内,方法以外,被static修饰的{} b. 作用:在类加载时,按照和静态属性定义的先后顺序,完成对静态属性的初始 化工作。 c. 类加载: I. 概念:JVM第一次使用一个类的时候,通过classPath(类路径)找到类对应 的.class文件,对文件进行读取,读取到类的信息(包名、类名、父类、属 性、方法、构造方法等),将读取到的信息保存在JVM内存中,一个类只进 行一次类加载。 II. 类加载的时机: (1) 第一次创建该类对象,先进行类加载,再完成对象的创建 (2) 第一次访问该类静态成员时,导致类进行类加载 (3) 子类类加载会先加载其父类: -->第一次访问子类的静态成员 -->第一次创建子类对象 先进行类加载: 先加载父类: 完成对父类静态属性的初始化工作 再加载子类: 完成对子类静态属于的初始化工作 再进行对象的创建: 分配空间(子类+父类) 先创建父类对象: 初始化父类的属性:动态代码块执行 调用父类的构造方法 再创建子类对象: 初始化子类的属性:子类的动态代码块执行 调用子类的构造方法 注意:只是声明引用不会导致类进行类加载。 4. static可以修饰内部类—>静态内部类 1. final可以修饰变量(局部变量、实例变量、静态变量) ① 被final修饰的变量是作用范围内的常量,只允许一次赋值,不允许更改。 ② final修饰的实例变量不再分配默认值 对其初始化的时机: a. 声明的同时对其初始化 b. 在构造方法中对其初始化 注意:必须保证每一个构造方法都对其初始化 ③ final修饰的静态变量不具有默认值 对其初始化的时机: a. 声明的同时对其初始化 b. 在静态代码块中对其初始化 注意:final修饰引用代表引用存储的对象不能改变; final修饰的变量为基本数据类型,则代表变量中的数值不允许改变。 2. final修饰的方法:可以被继承,但是不允许被覆盖 3. final修饰的类:不能被继承,即没有子类 例如:String、Math、System都被final修饰 1. 接口是一种标准,是接口的使用者和接口的实现者之间的约定。【理解】 2. 接口的语法:【基础重点】 ① 关键字:interface 语法:interface 接口名{} ② 接口编译之后生成对应 .class 文件 ③ 接口不能创建对象,但是可以声明引用 ④ 接口中没有构造方法 ⑤ 接口中的属性都是公开、静态、常量(默认的被 public static final 修饰) ⑥ 接口中的方法都是公开、抽象的(默认的被 public abstract修饰) 注意:接口不是类。 1. 语法: class 类名 implements 接口名{} 2. 注意:实现类如果不想成为抽象,则必须实现(覆盖)接口中所有的方法,而且实现接口 中的方法时,方法的访问修饰符必须是public. 3. 使用:接口名 引用名 = new 实现类类名(实参); ---->多态的应用 1. 接口之间是多继承关系: interface 接口名 extends 父接口名1,父接口名2{} 2. 类可以同时实现多个接口: class 类名 implements 接口名1,接口名2{} 注意:实现类如果不想成为抽象类,则需要实现所有接口中所有的方法。 3.类可以实现多个接口的同时继承一个父类:必须先继承后实现 class 类名 extends 父类名 implements 接口1,接口2{} 1. 引用之间相互强制转换,如果转换的双方有一方为接口类型,则编译一定通过,运行是 否通过,分为以下两种情况: ① 如果引用中存储的实际对象类型和转换的类型相匹配,则运行通过 ② 如果引用中存储的实际对象类型和转换的类型不匹配,则运行报错, 错误信息为: java.lang.ClassCastException(类型转换异常) 1. 扩充子类的能力 ① Java中类之间是单继承关系,当父类中定义的方法不足以满足子类的能力需求时, 则子类可以利用接口扩充自身的能力。 ② 通常将子类的主要功能定义在父类中,次要的功能定义在接口中。 2. 解耦合 接口定义好之后,接口的使用者和接口的实现者进行分离,利用多态,降低各模块之间 的耦合度,从而实现弱耦合性。 1. 接口定义好之后,先有接口的使用者(通常开发人员不参与),再有接口的实现者(开发人 员需要根据接口的规范给予实现)。 注意:接口回调时,只需要关注接口的实现部分。 面试题目:接口和抽象类的区别? 接口 抽象类 关键字 interface abstract class 属性 公开、静态、常量 实例变量、静态属性 成员方法 公开、抽象方法 抽象方法+非抽象方法 构造方法 没有 有 继承关系 多继承 单继承 接口和抽象类的相同点: ① 编译之后都会生成独立.class文件 ② 都不能创建对象 1. 内部类:在一个类的内部,定义了一个完整的类。 //外部类 class Outer{ //内部类 class Inner{} } 2. 内部类编译之后,会生成独立的.class文件,命名方式为: 外部类的类名$内部类的类名.class 3. 内部类可以访问外部类的私有成员,从而不破坏外部类的封装性。 1. 分类:成员内部类、静态内部类、局部内部类、匿名内部类【面试题目】 2. 成员内部类(类比于实例变量)【了解】 ① 位置:定义在类以内,方法以外。 ② 创建成员内部类的对象必须依赖于外部类的对象: Outer o = new Outer(); Outer.Inner i = o.new Inner(); ③ 成员内部类可以直接访问外部类的私有的属性 ④ 外部类的类名.this 指向外部类的当前对象 外部类类名.this.属性:访问外部类的属性 外部类类名.this.成员方法名(实参):访问外部类的成员方法 ⑤ 成员内部类中不允许定义静态成员 3. 静态内部类(类比于静态变量)【了解】 ① 位置:定义在类以内,方法以外,被static修饰 ② 静态内部类中可以定义静态成员和非静态成员 ③ 创建静态内部类的对象只需要依赖于外部类的类名: Outer.Inner i = new Outer.Inner(); ④ 访问静态内部类的静态成员时,直接利用类名即可: 外部类名.内部类名.静态属性 外部类名.内部类名.方法名(实参); ⑤ 静态内部类中可以直接访问外部类的静态成员(静态的属性和方法); 但是不可以直接访问外部类的非静态成员。 4. 局部内部类(类比局部变量) ① 位置:定义在方法以内 ② 创建局部内部类对象必须在定义它的方法内部,并且必须在定义位置后面的地方可 以对其创建对象。 ③ 局部内部类中可以访问定义它的方法内部的局部变量,但是要求局部变量必须加 final(java语法规定) 注意:JDK8.0以上版本,JVM默认为 被局部内部类访问的局部变量添加final修 饰符---->语法糖 5. 匿名内部类 ① 匿名内部类是特殊的局部内部类 ② 特点: a. 匿名内部类必须实现一个接口或是继承一个父类 b. 基于匿名内部类只能创建该类的一个对象,而且匿名内部类的定义和对象的创 建一起完成 ③ 语法: interface IA{ void m1(); } 方法中定义匿名内部类: IA ia = new IA(){ public void m1(){ //实现部分… } }; 注意:直接利用 ia引用操作匿名内部类的对象。 ④ 匿名内部类的 优点:简化代码 缺点:可读性差 1. 概念: ① Object是根类、超类,位于java.lang包中,是所有类的父类(直接父类或是间接父 类) ② Object 类中定义的方法是所有类默认具备的 ③ Obejct类型的引用可以存储任意类型的对象。 2. Object中常用的方法: ① final Class getClass():返回引用中实际存储的对象类型。 a. 实际开发的应用:判断两个引用中实际存储的对象类型是否一致。 b. 例如:a1.getClass() == a2.getClass(); 【应用重点】 类型一致-true 类型不一致-false ② int hashCode():返回对象的哈希码值(哈希码值是对象十六进制地址转换十进制的 整数结果) 注意:不同的对象具有不同的哈希码值(不同对象的地址不同) ③ String toString():返回值对象的字符串表示形式。【开发应用重点】 a. 应用:开发时通常将toString覆盖,利用对象信息拼凑一个String类型结果 b. 覆盖原则:将对象的所有属性拼凑成一个String结果作为返回值返回。 public String toString(){ return “name=”+this.name+",age="+this.age;//this. 可以省略 } c. 注意: get方法是获取单个属性的信息,并且不会改变属性的原有类型; toString方法是以字符串的形式展示所有属性信息,方便编程人员打印 对象所有信息。 ④ boolean equals(Object o):判断两个对象的内容是否相同,相同-true;不相同-false a. ==的应用: I. 如果 == 两端是基本数据类型的变量,则比较变量中存储的数值是否相同 II. 如果 == 两端是引用类型的变量,则比较变量中存储的对象的地址是否相 同 注意:开发时,通常应用 == 判断两个引用是否执行同一个对象: 引用名1 == 引用名2 —》结果为true,代表两个引用指向同一个对象,, 否则,指向不同的对象 b. equals方法的引用:Object中的equals方法默认比较两个引用中地址是否 一致,如果希望它能比较两个对象的内容是否一致,则需要覆盖equals方法, 覆盖的步骤如下: public boolean equals(Object o){ //将 this 和 o进行比较 //(1) 自反性:判断两个引用是否指向同样一个对象 if(this == o){ return true; } //(2)判断 o是否为空 if(o==null){ return false; } //(3) 判断两个引用中存储的实际对象类型是否一致 if(this.getClass()!=o.getClass()){ return false; } //(4) 强制类型转换–>对下一个步骤准备 当前对象类型 s = (当前对象类型)o; //(5) 将属性内容进行比较:基本数据类型:==引用:equals比较 if(this.age==s.age && this.name.equals(s.name)){ return true; }else{ return false; } 面试题目: 写出 == 和 euqals的区别? ⑤ void finalize(): 垃圾回收器在回收垃圾对象时,JVM自动调用的方法。【面试重点+ 性能调优】 a. 垃圾对象:没有任何引用指向的对象。 b. 垃圾回收器:JVM用于回收垃圾对象,简称GC(gc) c. 垃圾回收的目的:释放JVM内存空间,保证新创的对象空间可用。 d. 垃圾回收器回收垃圾对象的时机: I. 自动垃圾回收机制:当JVM内存耗尽,不能再为新创建的对象分配空间时, 垃圾回收器会一次性的将垃圾对象进行回收(垃圾回收回收垃圾对象,自动 调用finalize方法) II. 手动垃圾回收机制:使用 System.gc() 通知垃圾回收器回收垃圾对象,如 果垃圾回收器(GC)空闲,则立即回收;否则暂不回收。 面试题目:写出 final 和 finalize的区别? 分析:① final是修饰符, 修饰类:没有子类 修饰方法:允许被继承,不能被覆盖 修饰变量(局部变量、实例变量、静态变量):作用范围内的常量 ② finalize是方法名,垃圾回收器在回收垃圾对象时调用的方法 1. 概念:8种基本数据类型对应的对象类型,称为基本数据类型的包装类。(8个)【理解】 2. 包装类:(位于 java.lang 包中)【开发应用重点】 基本数据类型 包装类 byte Byte short Short int Integer long Long float Float double Double char Character boolean Boolean 3. 数据类型之间的转换: ① int 和Integer之间的转换 int --> Integer a. Integer i1 = new Integer(12);//构造方法 b. Integer i2 = Integer.valueOf(12);//静态方 Integer --> int a. int a1 = i2.intValue(); ② Integer 和 String 之间的转换 String —> Integer a. Integer i3 = new Integer(“12”);//构造方法 b. Integer i4 = Integer.valueOf(“12”);//静态方法 Integer --> String a. String s1 = i4.toString(); b. String s2 = i4+"";//利用字符串的拼接 ③ int 和 String 之间的转换 int —> String int a = 12; a. String s3 = a+""; String --> int 【开发应用重点】 a. **int n = Integer.parseInt(“128”);//**利用 静态方法 注意:String转换为 int/Integer时,必须保证转换的字符串是纯数字的,否则 运行报错,错误信息如下: java.lang.NumberFormatException(数字格式转换异常) 4. 自动的装箱和拆箱【理解+应用】 ① JDK5.0版本之后,基本数据类型和包装类型之间可以自动完成装箱和拆箱。 ② 自动的装箱:将基本的数据类型自动转换为对应的包装类型 自动的拆箱:将包装类型自动的转换为对应的基本数据类型 ③ 案例: Integer i = 12; //自动装箱 int a = i;//自动拆箱 ④ 注意:自动的装箱底层原理默认调用 静态方法 Integer.valueOf(int i)【面试重点】 public static Integer valueOf(int i){ if(i>=-128 && i<=127){ return … } return new Integer(i); } 注意:JAVA 为了提高JVM运行效率,对程序中常用的数据做了预先包装处理, 存储在常量池(缓冲区),缓冲的数据范围:-128~127.【面试难点】 5. 实际开发应用【开发应用】 ① 场景:将属性由之前的基本数据类型替换为对应的包装类型。 ② 作用:区分有效数据和无效数据,例如: 0 和 null/0.0 和 null 1. 创建字符串对象的两种方式:【面试题目】 ① String s1 = “hello”; 注意:这种创建字符串的方式只会产生一个对象,串池中产生(用于共享) ② String s2 = new String(“world”); 注意:这种创建字符串的方式会产生两个对象,一个在堆空间中,另一个在串池 中产生。 2. 常用方法: ① char charAt(int index):根据下标获取对应的字符 注意:String底层本质为 char类型的数组,所以字符串的下标范围:0~字符串的 长度-1 ② boolean contains(String s):判断s是否包含在当前字符串中,包含-true, 不包含-false. ③ boolean equals(String str):判断两个字符串内容是否相同 ④ int length():获取字符串的长度 注意: 获取数组的长度:数组名.length 遍历字符串: for(int i=0;i<字符串.length();i++){ char c = 字符串名.charAt(i); //操作 字符c } ⑤ String trime():去除字符串前后的空格。 3. 不可变长的字符串【面试题目】 ① 字符串是字面值的常量,一旦创建不允许改变,如果实现字符串的拼接,则会在原 文本的基础上拷贝一个副文本,在副文本上进行操作。 4. 可变长的字符串(位于 java.lang 中) ① StringBuffer: JDK1.0版本,线程安全,运行效率慢 StringBuilder: JDK5.0版本,线程不安全,运行效率高 ② 字符串的拼接:append 方法 ③ StringBuilder的字符串拼接效率高于 String 拼接 面试题目:写出 String 和 StringBuilder的区别? 写出 StringBuilder 和 StringBuffer的区别? 1. 作用:精确、计算浮点数。 2. 常用的构造方法: BigDecimal(String n) 3. 常用的方法: ① BigDecimal r1 = bd1.add(bd2); //加法 ② BigDecimal r2 = bd1.subtract(bd2);// bd1-bd2 减法 ③ BigDecimal r3 = bd1.multiply(bd2);//乘法 ④ BigDecimal r4 = bd1.divide(bd2,3,BigDecimal.ROUND_HALF_UP);//bd1/bd2 参数说明: 第一个参数:参与运算的除数(分母) 第二个参数:保留到小数点后几位 第三个参数:对小数的取舍模式,通常采用四舍五入BigDecimal.ROUND_HALF_UP ① 概念:是一种工具类,也是一种容器,可以存储数量不等的对象。 ② 位置:java.util包中 ③ 学习过程中的内容:接口的特点、接口的功能方法、接口的实现类、遍历集合中元素 ① 特点:存储object类型的对象。 ② 方法:【重点】 a. add(Object obj):往集合中添加元素。 b. boolean contains(Object obj):判断对象obj是否在当前集合中存在, 存在-true;不存在-false. c. boolean remove(Object obj):将对象obj从当前集合中移除。 d. int size():获取集合中元素的个数 ③ 实现类:没有直接的实现类 ④ 遍历方式:详见子接口的实现类。 ① 特点:存储Object对象,有序、有下标、元素允许重复。 下标范围:0~有效元素的个数-1 (0~size-1) ② 方法: a. add(int index,Object obj):将对象obj插入到指定位置。 b. Object get(int index):根据下标获取指定集合元素的内容。 c. Object remove(int index):将指定下标元素从当前集合中删除,并返回被删除 的对象 d. Object set(int index,Object obj):将集合中指定元素的内容修改,并返回修改 之前的元素内容。 ③ 实现类:ArrayList(底端用数组实现)【开发重点】 面试重点:不同实现类的区别: ArrayList:底层数组实现,查询快,增删慢。 JDK1.2 版本,线程不安全,运行效率快。 Vector:底层数组实现,查询快,增删慢。 JDK1.0 版本,线程安全,运行效率慢。 LinkedList:底层链表实现,查询效率低,增删快。 ④ 遍历: a. 下标遍历: for(int i=0;i //根据下标获取对应的元素内容 System.out.println(list.get(i)); } b. forEach遍历: 语法: for(数据类型 变量名:集合名字){ } 注意:数据类型取决于集合元素的数据类型 如果集合加了泛型,数据类型取决于泛型的类型。 泛型集合:数据安全的集合。泛型强制约束集合中元素数据类型要一致。 1. 1泛型类:【理解】 ① class 类名<泛型标识1,泛型标识2>{ } 注意:泛型标识通常用T/E/K/V ② 泛型类创建对象时,指定泛型标识代表的具体数据类型: 类名<具体数据类型> 对象名=new 类名<具体的数据类型>(); 注意:如果创建对象没有指定泛型标识代表的具体数据类型,默认的是Object类型。 1.2 泛型接口:jdk5.0之后可以定义泛型接口。 【理解】 ① 语法: interface 接口名<泛型标识1,泛型标识2>{} 例如: interface IA{} ② 实现类: 第一种方式: class ClassA implements IA<具体数据类型>{} 第二种方式: class ClassB implements IA{} 注意:在创建对象时,指定泛型类型。 1.3 Java提供操作集合的工具类:Collections.【了解】 常用方法: ① public static void reverse(List list):倒置 ② public static void shuffle(List list):随机显示 ③ public static void sort(List list):排序 注意:如果集合中存储的对象类型是自定义类型的对象,则需要让对应的类实现 Comparable接口,从而实现compareTo方法。 面试题目:区分Collection和Collections。 Collection集合体系中的根接口。 Collections操作集合的工具类。 1. 特点:存储Object类的对象,无序、无下标、元素的内容不允许重复。 2. 方法:方法全部继承于父接口Collection 3. 实现类: HashSet【开发重点】 如果自定义类型的对象存储在HashSet集合中,为了保证元素的内容不重复,必须做到: ① 覆盖hashCode方法 目的:必须保证相同内容的对象返回相同的hashCode码值;为了提高效率,不同 内容的对象尽量返回不同的hashCode码值。 覆盖原则:将所有的属性拼凑为一个int值作为返回值。 例如: public int hashCode(){ return this.age+this.name.hashCode(); } ② 覆盖equals方法 : 必须保证内容相同的对象结果返回true. - SortedSet:是Set的子接口【了解】 ① 特点:存储Object类型的对象,无序、无下标、元素内容不允许重复。可以 根据元素内容自动排序。 4. 实现类:TreeSet 自定义类型的对象存储在TreeSet集合中,如果compareTo的结果返回值为0,则代 表相同内容的元素,拒绝添加。 5. 遍历:forEach 1. 特点:【重点】 ① 存储任意的键值对(key-value) ② 键:无序、无下标、元素不允许重复(唯一性) ③ 值: 无序、无下标、元素允许重复 2. 方法: ① V put(K key,V value):将一个键值对存储在map集合中。如果键在map中已经存 在,则用新的数值覆盖旧值,将旧值作为返回值返回;如果键在map不存在,值直 接存储,返回null.【重点】 ② V remove(K key):根据key删除map中一个键值对,同时将删除值作为返回值返 回。 ③ V get(K key):根据键获取值。【开发重点】 ④ boolean containsKey(K key):判断map集合中是否包含此键,包含-true; 不包含-false. ⑤ boolean containsValue(V value):判断map集合中是否包含此value,包含-true; 不包含-false. ⑥ int size():获取键值对的个数。 3. 实现类:HashMap【开发应用重点】 ① HashMap【重点】:JDK1.2 版本,线程不安全,运行效率快。 允许null作为key或是value. ② Hashtable:JDK1.0 版本,线程安全,运行效率慢。 不允许null作为key或是value. ③ Properties:是Hashtable的子类,键和值必须是String类型。 作用:通常用于读取配置文件。 ④ TreeMap:是SortedMap的实现类(SortedMap是Map的子接口)。 作用:可以对键自动排序。 面试重点: HashMap和Hashtable的区别: HashMap:允许null作为键和值,线程不安全,效率高 HashTable:不允许null作为键值,线程安全,效率低 4. map遍历: ① 键遍历:【开发应用重点】 通过keySet方法获取map中所有的键:Set keySet(); Set<键的数据类型> ks=map.keySet(); for(键的数据类型 key:ks){ //通过键获取值的内容 值的数据类型 value=map.get(); } ② 值遍历: 通过values方法获取map中所有的值:Collection values(); Collection<值的数据类型> vs=map.values(); for(值的数据类型 value:vs){ //… } ③ 键值对遍历:【开发应用重点】 通过entrySet方法获取map中所有的键值对: Set Set for(Map.Entry K key=kv.getKey();//获取键 V value=kv.getValue();//获取值 1.***集合和数组的区别:(集合是存储对象的容器) a.长度区别:数组长度固定,集合长度可变 b.存储元素数据类型:数组可以存储基本数据类型和引用数据类型,集合只能存储引 用数据类型 ①ArrayList:底层数组实现,查询快增删慢,线程不安全,效率高 ②Vector:底层数组实现,查询快增删慢,线程安全,效率低 ③LinkedList:底层链表实现,查询慢增删快,线程不安全,效率高 ① HashSet(无序,唯一):如果一个类没有覆盖hashCode和equals方法,会默认 调用Object类中的方法,哈希值会不同,比较的也是两个引用的首地址。 (底层哈希表实现,无序,唯一) ***HashSet如何保证的唯一: 添加底层依靠的两个方法:①hashCode();②equals(); 执行步骤: a.首先执行hashCode(),判断对象的哈希值是否相同。 b.相同–>执行equals(),判断内容是否相同,相同->不存储 不同->存储 覆盖HashCode方法: public int hashCode(){ return this.name.hashCode()+this.age+this.score; } --子类LinkedHashSet: 底层哈希表和链表实现(保证元素的有序和唯一) ② TreeSet:(排序,唯一) 底层:红黑自平衡二叉树 排序方式:自然排序–>必须实现Comparable接口,覆盖compareTo方法 ***覆盖compareTo方法 public int compareTo(Student o) { //主要条件:姓名长度 ,从长到短 int num = o.name.length() - this.name.length(); //次要条件:如果姓名的长度相同,也许姓名不同(按照字典的顺序) int num2 = num == 0?this.name.compareTo(o.name):num; //次要条件,如果姓名相同,也许年龄不同 int num3 = num2 == 0?this.age - o.age:num2; return num3; } 4.遍历Collection代码: ①toArray() Object[] obj = list.toArray(); for(Object o:obj){ System.out.println(o); } ②迭代器 Iterator it = list.iterator(); while(it.hasNext()){ System.out.println(it.next()); } ③普通for(List独有) for(int i = 0; i System.out.println(list.get(i)); } ④foreach for (String s : list) { System.out.println(s); } 5.元素去重:*** ①遍历旧集合,得到每一个元素 for (int i = 0; i < list.size(); i++) { String s = (String)list.get(i);//s:集合中的每一个元素 System.out.println(s); ②判断当前元素新集合中是否存在 if(list2.contains(s)){ 元素重复 }else{ 不重复 list2.add(s); } } System.out.println(list2); 6.Collection中的功能 ①.添加功能 boolean add(Object e) boolean addAll(Collection c): 添加一个集合的元素 ②.删除功能: void clear():移除集合中所有的元素 boolean remove(Object o):删除一个指定的元素 boolean removeAll(Collection c):移除一个集合的元素 ③.判断功能: boolean contains(Object o):判断集合中是否包含指定的元素 boolean isEmpty():判断集合是否为空 ④.获取功能: int size():获取集合的长度 获取数组的长度:数组名.length 获取字符串长度的方法:对象.length() boolean retainAll(Collection c):交集 Iterator iterator():使用迭代器遍历 ⑤.转换功能: Object[] toArray():将集合转数组 ***Map和Collection区别: a.Map存储键值对,健唯一,值可重复 b.Collection存储单个元素,子接口List有序,可重复;无序,唯一。 ①.HashMap:唯一,无序 底层哈希表实现 ②.TreeMap:排序,唯一 底层:红黑自平衡二叉树(保证键从小到大) 3.LinkedHashMap:唯一,有序 底层:哈希表,链表实现 HashMap:允许null作为键和值,线程不安全,效率高 HashTable:不允许null作为键值,线程安全,效率低 问题1:(Map) 给定一个字符串,请输出该字符串由哪些字符组成,每个字符出现几次? public class Test { public static void main(String[] args) { //定义一个字符串 String s = “hheewwwor”; HashMap for(int i = 0; i char ch = s.charAt(i); System.out.println(ch); //判断集合中是否有ch键 if(hm.containsKey(ch)){ //true:集合中存在这个键 Integer value = hm.get(ch); value += 1; hm.put(ch, value); }else{ //false:集合中没有这个键 hm.put(ch, 1); } } System.out.println(hm); } } ***遍历Map: Set keys = hm.keySet();//存储所有的键 for(String key: keys){//key:得到每一个键 //根据键获取值 Student value = hm.get(key); System.out.println(key +" "+value); } 1.添加功能: V put(K key, V value):存储键值对 如果该键第一次被存储,返回null,除第一次以外会返回该键上一次添加的值 2.删除功能: void clear():删除所有键值对 V remove(Object key):根据键删除键值对,返回该键对应的值 3.判断功能: boolean containsKey(Object key):是否包含指定的键 boolean containsValue(Object value):是否包含指定的值 boolean isEmpty():集合是否为空 4.获取功能: *int size():得到集合的长度 *V get(Object key):根据键获取值 *Set keySet():得到集合中所有的键存放在set集合中 *Collection values():得到集合中所有的值 Set } [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0tZhHZcX-1591751992764)(file:///C:/Users/Shallum/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg)] ① 概念:程序运行过程中出现的一些不正常的情况。 ② 异常的处理的必要性:减少用户不必要的损失。 1. 所有的异常的父类是Throwable类,位于java.lang 常用的方法: ① String getMessage():获取String类型的异常信息。 ② void printStackTrace():获取方法调用栈中,异常详细的信息。 2. Throwable具有两个直接的子类: ① Error:表示仅靠程序本身无法恢复的严重错误,例如:内存不足或是方法调用栈溢出 特点:在大多数的情况下,遇到这样的错误,程序无法处理。 ② Exception:分类两类 a. RuntimeException:称为运行时异常、未检查异常(RuntimeException+其所有 的子类) 特点:编译器编译时不会检测它,运行时报错。这类异常可以避免,可以 处理也可以不处理。 常见的运行时异常: I. 数组下标越界:java.lang.ArrayIndexOutOfBoundsException II. 类型转换异常:java.lang.ClassCastException III. 空指针异常:java.lang.NullPointerException IV. 数字格式转换异常:java.lang.NumberFormatException b. 非RuntimeException:非运行时异常、已检查异常(和RuntimeException异 常没有继承关系的类) 特点:编译器编译时检测它,出现这类异常,编译不通过,必须处理。 1. 自动产生异常:【理解】 程序在运行过程中,遇到出错的代码,则自动产生异常,程序自动终止。 2. 手动产生异常【开发重点】 ① 语法: throw new 异常类名(实参); ② 位置:手动产生异常,必须定义在方法内部。 ③ 结果:相当于return语句,导致程序的终止。 沿着方法的调用链反向进行传递,最终传递给JVM,导致程序终止。 1. 消极处理异常 ① 关键字: throws ,声明异常,定义在方法的声明后面。 ② 语法:修饰符 返回值类型 方法名(形参列表)throws 异常类名{} ③ 作用:采用消极处理异常的方式只是将异常传递,推卸责任,程序仍然会被终止。 但 是可以让非运行时异常在编译时通过。 2. 积极处理异常 ① 语法: try{ //可能出现的异常的语句 }catch(异常类名 e){ //将捕获到的异常,自动赋值给e引用 //一旦出现异常,执行的语句 } ② 注意: a. try 后面可以跟多个 catch,try一旦出现异常,从第一个catch依次往下匹配, 直到匹配成功。 b. catch中可以利用多态,通过父类型处理异常,可以处理的异常类型: 本类型+所有的子类的异常。 但是:父类型的catch必须定义在其子类型catch的后面。 c. catch中只能处理try中可能出现的非运行时异常。 catch中可以处理任意的运行时异常,即使在try中没有出现的可能性。【了解】 d. 积极处理异常的同时可以声明抛出异常。 e. finally中的语句是必须执行的语句: 语法: try{ //… }catch(异常类名 e){ //… }finally{ //不管有没有异常,必须执行的语句 } 注意:finally中一般不放return语句,finally一般用于释放资源。 区分:final 、finalize、 finally【面试题目】 final是修饰符:可以修饰变量、方法、类 final修饰的变量是作用范围内常量 final修饰的方法可以被继承,不能被覆盖 final修饰的类不能被继承,即没有子类。 finalize是方法的名字:垃圾回收器回收垃圾对象时,调用的方法 finally是 try…catch…finally结构,finally中的语句不管异常一定被执行; finally一 般用于释放资源。 自定义异常类通常定义为:运行时异常。 一个构造方法为无参数的构造方法; 另一个构造方法为带有String类型参数的构造方法: 利用super(message),message描述异常的String信息。 子类的方法名、参数列表、返回值类型必须和父类相同 子类的访问修饰符必须和父类相同或是更宽 子类不能抛出比父类更多、更宽的异常 1. 概念:流是内存和其他存储设备中传输数据的通道、管道。 2. 分类 ① 按方向分:(以JVM为参照物)【重点】 输入流:将<存储设备>中的数据,读入到<内存>中。 输出流:将<内存>中的数据,写入到<存储设备>中。 ② 按单位分: 字节流:以字节为单位,可以操作所有类型的文件。 字符流:以字符为单位,只能操作文本文件。 (可以用记事本打开的文件,例如:.java/.txt/.c/.html) ③ 按功能分: 节点流:具有基本的读写功能。 过滤流:在节点流的基础上,增强新的功能。 1. 字节流的父类(抽象类) ① InputStream:字节输入流—》读操作:read ② OutputStream:字节输出流—》写操作:write 2. 字节节点流【重点】 ① FileOutputStream:文件字节输出流 常用的构造方法: a.FileOutputStream fos = new FileOutputStream(“E:/CoreJava/test/a.txt”); I. 参数:指定文件的路径E:/CoreJava/test/a.txt或是 E: CoreJava test a.txt II. 如果指定的文件不存在,系统默认新创建一个文件。 但是如果指定的文件夹不存在,则系统报错,错误信息: java.io.FileNotFoundException (系统找不到指定的路径。) III. 绝对路径:盘符:/文件夹名/文件名 b. FileOutputStream fos = new FileOutputStream(“a.txt”); I.参数:指定文件的路径,默认在当前项目的根目录下查找文件,没有则创建 II. 相对路径:默认在当前项目的根目录下查找文件 c. FileOutputStream fos = new FileOutputStream(“file/a.txt”);【开发应用】 d. FileOutputStream fos = new FileOutputStream(“file/a.txt”,true); I. 第二个参数:类型是 boolean true-在原有内容上追加(不覆盖原有内容) false-覆盖原有的内容(默认) 常用的方法: a. public void write(int b):将单个字节的内容写入到文件中。 b. public void write(byte[] bs):一次性将多个字节写入到文件中。 c. public void write(byte[] bs,int off,int len):一次性将多个字节写入到文件中,将 bs数组中一部分内容写入文件中,起始下标off,写入长度len ② FileInputStream:文件字节输入流 常用的构造方法: a. FileInputStream fis = new FileInputStream(“f.txt”); I. 参数:代表文件的路径,如果指定文件不存在,系统不会自动创建,运行 报错,错误信息: **java.io.FileNotFoundException(**系统找不到指定的文件。) 常用的方法: a. public int read():一次性读取一个字节的内容,返回值代表读取的内容,如果达 到文件的尾部,则返回-1. 将文件中内容一次性读取? while(true){ int r = fis.read(); if(r==-1){ break; } System.out.println((char)r); } b. public int read(byte[] bs):一次性读取多个字节的内容,将读取的字节内容自 动存储到bs数组中,返回值代表实际读取的字节个数。 c. public int read(byte[] bs,int off,int len):一次性读取多个字节的内容,将读取 的字节内容存储到数组bs中(存储的起始下标off,读取的个数len),返回值代表实 际读取的字节个数。 思考:如何实现文件的拷贝??? while(true){ int r = fis.read(); if(r==-1) break; fos.write®; } 3. 过滤流 ① BufferedInputStream/BufferedOutputStream a. 缓冲流,提高IO读写效率,减少访问磁盘的次数。 b. 数据存储在缓冲中,利用flush方法将缓冲区的数据清空,(写入到文件中); 或是直接利用close方法清空缓冲区。 ② DataOutputStream/DataInputStream a. 操作8种基本数据类型 readByte()/readShort()/readInt()/readLong()/readFloat()/readDoubl e()/writeByte(形参)/writeShort(形参)… b. 可以操作字符串:readUTF() / writeUTF(参数) ③ ObjectOutputStream/ObjectInputStream a. 具有缓冲作用 b. 可以操作8种基本数据类型/String c. 可以操作对象 writeObject(Object o):将对象写入到文件中 readObject():从文件中读取一个对象的内容,返回值类型是Object. ④对象序列化: 概念:将对象放在流上进行传输的过程称为对象序列化。【重点】 要求:参与对象序列化的对象是可序列化的,可序列化的要求是 对象的类实现java.io.Serializable接口。【重点】 注意:① 被transient修饰的属性不参与对象序列化。 ② 达到文件尾部的标志:java.io.EOFException ③ 如果参与对象序列化的对象中的属性是自定义类型,则该对象也必须是 可序列化的。 ④ 如果对集合进行对象序列化,则必须保证集合中所有的元素 都是可序列 化的。 1. 常用编码: ① ISO8859-1 :西欧 ,底端存储占用1B ② GBK 简体中文 GB2312 GB18030 ⑤ BIG5 台湾-繁体中文 ⑥ UTF-8 万国码,底端采用动态编码,中文占 2 ~ 3个字节,英文符号:1B 如果编码方式和解码方式不一致,会导致乱码。 2. 字符流的父类(抽象类) ① Writer:字符输出流—》写操作 ② Reader:字符输入流—》读操作 3. 节点流 ① FileWriter:文件字符输出流 a. public void write(int b):将单个字符写入文件中 b. public void write(String str):将多个字符一次性写入到文件中 c. public void write(char[] c):将多个字符一次性写入到文件中 ② FileReader:文件字符输入流 a. public int read():一次读取一个字符的内容,达到文件的尾部,返回—1. b. public int read(char[] c):一次性读取多个字符的内容,并且将读取的字符内容存 储到数组中,返回值代表实际读取的字符个数,达到文件尾部,则返回-1. c. public int read(char[] c,int off,int len):一次性读取多个字符的内容,将读取的内 容存储到字符数组中,存储下标为off,读取的字符个数为len,达到文件尾部,返 回-1。 4. 过滤流【重点】 BufferedReader/PrintWriter ① BufferedReader: 操作:public String readLine():一次性读取一个文本行的内容。达到文件的尾部, 返回null. ② PrintWriter: a. 可以操作8种基本数据类型 b. 可以将String写入到文件中 print(参数):将内容写入到文件中不换行 println(参数):将内容写入到文件中,自动换行。 c. 可以将对象的内容写入到文件中: println(Object o)/print(Object o) 注意:将对象的toString方法的返回的String结果写入到文件中。 ① OutputStreamWriter/InputStreamReader a. 作用:将字节流转换成字符流,同时可以设置编解码方式。 步骤小结:【重点】 ① 创建字节节点流 ② 创建桥转换流:字节流–》字符流,同时设置编解码方式 ③ 包装过滤流:目的是增强读写操作 ④ 读写操作 ⑤ 关闭流:关闭最外层流 1. File是对文件本身操作,例如:删除文件、改名字等。 IO流是对文件的内容进行操作,读或是写操作。 2. 常用方法: ① File(String pathName):执行操作的文件、文件夹的路径 ② String getName():获取文件/文件名字,文件包含扩展名 ③ String getAbsolutePath():获取文件、文件夹的绝对路径 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TM2PIVvM-1591751992767)(file:///C:/Users/Shallum/AppData/Local/Temp/msohtmlclip1/01/clip_image004.jpg)] 1. 概念: 进程是指操作系统(OS)中并发执行的多个任务。 2. 并发执行的原理:宏观并行,微观串行。 1. 概念:线程是一个进程中并发执行的多个程序逻辑(任务); 线程是进程的执行单位。(线程被称为轻量级进程) 【理解】 ① CPU:获取OS分配的CPU时间片。 ② 数据:堆空间共享,栈空间独立。 堆空间:存储对象,堆空间共享。 栈空间:存储局部变量,栈空间独立。 ③ 代码:代码实现多线程【开发应用重点】 a. 第一种实现多线程 I. 自定义类继承Thread类,覆盖run方法 II. 创建自定义类对象 MyThread t=new MyThread(); III. 开启线程:调用start()方法 t.start();//JVM会自动调用run方法 b. 第二种实现多线程: I. 自定义类实现Runnable接口,同时实现run方法 II. 创建自定义类对象 MyTarget tg=new MyTarget(); III. 创建Thread对象,同时将目标对象作为参数传递 Thread t=new Thread(tg); IV. 开启线程:调用start方法(t.start() 1. 状态图详见pdf.【理解】 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GpDIfnD7-1591751992770)(file:///C:/Users/Shallum/AppData/Local/Temp/msohtmlclip1/01/clip_image006.jpg)] 2. 常见方法: ① sleep(long ms):让当前线程处于休眠状态,单位是毫秒。处于休眠状态的线程会让 出CPU时间片,但是不释放锁标记。调用sleep方法的线程进入限期等待状态(Timed Waiting)。 ② join():加入,合并到自身线程任务中,优先执行。 例如:main函数中调用t.join()//主线程让t线程优先执行。 1. 临界资源:多线程并发时,多个线程共享的同一个对象。 3. 线程同步:多线程并发时,为了保证临界资源的正确性,从而不破坏程序中原子操作。 4. 线程同步的方式:【开发应用重点】 ① 同步代码块:对临界资源对象加锁 a. 位置:定义在方法内部 b. 语法: synchronized(临界资源){ //原子操作… } c. 线程必须获取临界资源的锁标记,才能执行同步代码块中{}的内容;而且{}中的 内容全部执行完毕,才释放锁标记。如果线程没有获取临界资源的锁标记,则进 入阻塞状态(Blocked状态),只有获取类锁标记,才能从阻塞状态出来, 同时拥有CPU,才能执行{}中的内容。 ② 同步方法: a. synchronized 修饰方法 b. 修饰符 synchronized 返回值类型 方法名(形参){ //原子操作… } 相当于: synchronized(this){ //原子操作… } 1. wait():等待 ① 位置:必须使用在该对象的同步代码块中。 ② 作用:让当前线程处于等待状态 ③ 注意:wait会让当前线程释放拥有的对象的锁标记,同时释放CPU. 2. notify()/notifyAll():通知 ① notify:通知一个线程从等待状态出来; notifyAll:通知所有的线程从等待状态出来。 ② 位置:必须使用在该对象操作的同步代码块中。 ③ notify/notifyAll:只是通知的作用,不会让当前线程释放锁标记和CPU. 面试重点: sleep(long ms)和wait()方法的区别????? **六、**什么是ThreadLocal ThreadLocal是一个本地线程副本变量工具类。主要用于将私有线程和该线程存放的副本对象 做一个映射,各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用,特别 适用于各个线程依赖不通的变量值完成操作的场景。由于ThreadLocalMap的key是弱引用, 而Value是强引用。这就导致了一个问题,ThreadLocal在没有外部对象强引用时,发生GC 时弱引用Key会被回收,而Value不会回收,如果创建ThreadLocal的线程一直持续运行, 那么这个Entry对象中的value就有可能一直得不到回收,发生内存泄露。 总结:每个ThreadLocal只能保存一个变量副本,如果想要上线一个线程能够保存多个副本以 上,就需要创建多个ThreadLocal。ThreadLocal内部的ThreadLocalMap键为弱引用,会 有内存泄漏的风险。适用于无状态,副本变量独立后不影响业务逻辑的高并发场景。如果如果 业务逻辑强依赖于副本变量,则不适合用ThreadLocal解决,需要另寻解决方案。 1. 概念:单例是常见的设计模式,在Java中,单例对象必须保证JVM中只有一个该类的 实例对象存在。 2. 单例的代码实现: //饿汉式: 优点:并发效率高 缺点:空间利用率低 class Single1{ private static final Single1 s=new Single1(); private Single1(){} public static Single1 getInstance(){ return s; } } //懒汉式: 优点:空间利用率高 缺点:并发效率低 class Single2{ private static Single2 s; private Single2(){} public synchronized static Single2 getInstance(){ if(s==null){ s=new Single2(); } return s; } } 1. 概念:【理解】 ① 类的对象:基于定义好的一个类,创建该类的实例对象。 new出来的对象都是类的对象 ② 类对象:类加载的产物,封装了该类的所有的信息 (类名、包名、父类、接口、方法、属性等)。 ① 通过类的对象获取类对象 Student s=new Student(); Class c1=s.getClass(); ② 使用类名获取类对象: Class c2=Student.class; ③ 使用Class中静态方法 forName获取类对象 Class c3=Class.forName(“包名.类名”); 注意:类名必须是全类名:包名.类名 ① 缺点:可读性差 ② 优点:可以使代码更加灵活通用。一般应用在底层开发,例如框架等。 ①. 获取.class文件对象 A.Object类中的方法:Class getClass() B.数据类型.class C.Class类中有一个静态方法:static Class forName(String className) 注意:className传递类的全路径(包名+类名) 5. 获取构造方法: Constructor>[] getConstructors():所有公共构造方法 Constructor>[] getDeclaredConstructors():获取所有的构造方法 Constructor getConstructor(Class>… parameterTypes):指定公共构造方法 Constructor getDeclaredConstructor(Class<>parameterTypes)指定构造方法 Constructor类中创建对象的方法: Object newInstance(Object… initargs):通过构造方法创建对象获取属性: Field[] getFields():获取所有public修饰的属性 Field[] getDeclaredFields():获取所有的属性 Field getField(String name) :获取单个的public修饰的属性 Field getDeclaredField(String name) :获取指定的属性 Field的类中为属性赋值的方法: void set(Object obj, Object value) 获取方法: Method[] getMethods():获取所有public修饰的方法 Method[] getDeclaredMethods() :获取所有的方法 Method getMethod(String name, Class>… parameterTypes):获取指定公 共修饰的方法 Method getDeclaredMethod(String name, Class>… parameterTypes):获 取指定的方法 Method类中的方法: Object invoke(Object obj, Object… args):执行当前获取到的方法 1. 简单工厂设计模式:测试类不必创建对象,通过工厂类创建对象 2. 单例设计模式:保证内存中只有一个对象 A.饿汉式:类一加载就会创建对象 B.懒汉式:什么时候用到在创建对象 如何保证内存中只有一个对象: 1.构造方法私有化 2.类中成员位置创建一个对象 3.提供公开的访问方式 面试题:单例设计模式的思想是什么?请写一段代码体现?(掌握) 思想:保证内存中只有一个对象 开发:饿汉式(多线程环境下不会出现问题) 面试:懒汉式(多线程环境下存在问题) ☆☆☆CoreJava完结☆☆☆四、可变长的参数【理解+阅读API时应用】
五、排序(小–>大)【面试重点】
六、二维数组【了解】
第七章 面向对象
一、对象【理解】
二、类的组成【语法基础重点】
三、对象的创建
四、对象创建的过程【理解】
五、this 的使用【开发应用重点】
六、引用【理解】
第八章 面向对象的三大特性
一、封装
二、继承
三、多态
第九章 三个修饰符
一、abstract(抽象的)
二、static(静态的)
三、final(最终的)
第十章 接口
一、概念
二、接口的实现类【基础重点】
三、接口的继承关系【基础重点】
四、接口多继承的影响【了解】
五、接口的好处【理解】
六、接口的回调【理解】
第十一章 内部类
一、概念【理解】
二、内部类分类
第十二章 常用类
一、Object类
二、包装类
三、String类(位于 java.lang 中)
四、BigDecemal类(位于 java.math包中)【了解】
第十三章 集合
**一、**集合【理解即可】
二、Collection集合(父接口)
三、子接口:List集合【重点】
四、子接口:Set集合【重点】
五、Map集合【开发重点】
五、总结版Collection集合
六、总结版Map集合
第十四章 异常
一、异常【理解】
二、异常的分类【面试重点】
三、异常的产生
四、异常的传递:【理解】
五、异常的处理:【开发应用重点】
六、自定义异常类
七、方法的覆盖(终结版)【重点】
第十五章 IO流
一、IO简介(位于java.io包中)
二、字节流
三、字符流
四、File类
第十六章 线程
一、进程【理解】
二、线程
三、线程状态
四、线程同步【重点】
五、线程通信【了解】
第十七章 反射
一 、单例
二、反射
三.设计模式