java基础回顾
第一阶段—> 计算机基础
第一阶段大纲
1. JDK JRE JVM
JVM:(Java Virtual Machine)Java虚拟机,我们在进行java开发的时候,首先需要编写java源代码,
源代码经过编译器编译,编译成二进制文件(字节码文件.class文件),经过解释器对字节码文件进行解释翻译才能执行。
而JVM中包含了解释器(不同操作系统解释器不一样),所以java跨平台就是通过JVM来实现的。
确切的来说,java跨平台是因为JVM中的解释器跨平台JDK:(Java Development Kit)Java开发工具包,java开发必备。包括
- Oracle JDK
- Open JDK
JRE: (Java Runtime Environment)Java运行环境,运行java程序必备 注意:Java9之后JDK中不再有JRE了
Java 特点是:垃圾回收机制
GC 自动回收内存中没有指针引用的堆内存空间
————————————————————————————————
2、标识符命名规范
一、简单的说,Java中凡是可以由程序员自己起名字的都叫标识符。其涉及到的结构有:包名、类名、接口名、变量名、方法名、常量名。
二、标识符的命名规则
① 由26个英文字母大小写,0-9,_ 或 $ 组成。② 数字不可以开头。
③不可以使用关键字(class、int等)和保留字(goto和const),但能包含关键字保留字。
④ Java中严格区分大小写,长度无限制。(例:class×,Class√) ⑤ 标识符不能包含空格。
包名:多单词组成时所有字母都小写。(例:aaabbbccc)
类名、接口名:多单词组成时,所有单词的首字母大写。(例:AaaBbbCcc)
变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写。(例:aaaBbbCcc)
常量名:所有字母都大写,多单词时每个单词之间用下划线_连接。(例:AAA_BBB_CCC)
————————————————————————————————
3、类名与字节码文件关系
java文件,被虚拟机编译后的文件就是:“.class字节码文件”。比如在cmd命令行中输入“java Student.java”,就会得到一个.class文件“Student.class”。
1、编译:编译的不是源文件,而是源文件中的类,会将源文件中的每个类都编译成一个个字节码文件,字节码文件的名称就是类的名称;
2、一个源文件可以定义多个类,文件中类的类名不能相同、如果这多个类没有任何一个类被public修饰,那么源文件的名字任意;
3、如果源文件中的多个类中有一个类被public修饰,那么这个类就是该源文件的主类,那么源文件的名称与该主类的名称一致;
4、源文件中可以定义多个类,一般一个源文件只定义一个类,且类被public修饰,那么源文件名称与类名一致;
5、执行:执行的是字节码文件中类的主方法,所以是执行字节码文件时,就自动调用该类的主方法。
强调
如果源文件中的代码被修改,需要重新编译,否则字节码文件中的内容仍是上次编译的内容,重新编译之后生成新的字节码文件会自动覆盖原字节码文件。
————————————————————————————————
4、变量
Java语言支持的变量类型有:
类变量:独立于方法之外的变量,用 static 修饰。
实例变量:独立于方法之外的变量,不过没有 static 修饰。
局部变量:类的方法中的变量。
public class Var{
static int a=0; // 静态变量(类变量)
String str="hello world"; // 非静态变量(实例变量)
public void method(){
int i =0; // 局部变量
}
}
Java 局部变量
局部变量声明在方法、构造方法或者语句块中; 局部变量在方法、构造方法、或者语句块被执行的时候创建,当它们执行完成后,变量将会被销毁;
访问修饰符不能用于局部变量; 局部变量只在声明它的方法、构造方法或者语句块中可见; 局部变量是在栈上分配的。
局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用。 实例 1
在以下实例中age是一个局部变量。定义在pupAge()方法中,它的作用域就限制在这个方法中。
public class Test{
public void pupAge(){
int age = 0;
age = age + 7;
System.out.println("小狗的年龄是: " + age);
}
//
public static void main(String[] args){
Test test = new Test();
test.pupAge();//
}
}
成员变量和局部变量的区别
作用域
成员变量:针对整个类有效。
局部变量:只在某个范围内有效。(一般指的就是方法,语句体内)
存储位置成员变量:随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中。
局部变量:在方法被调用,或者语句被执行的时候存在,存储在栈内存中。当方法调用完,或者语句结束后,就自动释放。 生命周期成员变量:随着对象的创建而存在,随着对象的消失而消失 局部变量:当方法调用完,或者语句结束后,就自动释放。 初始值
成员变量:有默认初始值。
局部变量:没有默认初始值,使用前必须赋值。
使用原则 在使用变量时需要遵循的原则为:就近原则 首先在局部范围找,有就使用;接着在成员位置找。
————————————————————————————————
5、常量
Java 语言使用 final 关键字来定义一个常量,其语法如下所示:
final 关键字表示最终的,它可以修改很多元素,修饰变量就变成了常量。例如,以下语句使用 final 关键字声明常量。
public class HelloWorld {
// 静态常量
public static final double PI = 3.14;
// 声明成员常量
final int y = 10;
public static void main(String[] args) {
// 声明局部常量
final double x = 3.3;
}
}
常量有三种类型:静态常量、成员常量和局部常量。
代码第 3 行的是声明静态常量,使用在 final 之前 public static 修饰。public static
修饰的常量作用域是全局的,不需要创建对象就可以访问它,在类外部访问形式为 HelloWorld. PI。
————————————————————————————————
6、数据类型
八大基本类型和引用类型
Java 各个类型的默认值:
引用类型 在Java中,引用类型指向一个对象,指向对象的变量是引用变量。
对象、数组都是引用数据类型。
所有引用类型的默认值都是null。
一个引用变量可以用来引用任何与之兼容的类型。
————————————————————————————————
7—1、0 流程语句
顺序结构 : 从上到下从左到右(默认)
选择结构 :满足条件执行相应的代码(if…else、switch)
循环结构 :
重复执行一段代码(控制执行次数)(for、while、do…while)
————————————————————————————————
7—1、1 if 分支结构
if
else
else if
单选泽|单分支 if
单选泽|单分支 **
if
if(boolean表达式){语句体;}执行流程 :
1.boolean表达式,得到boolean结果
2.如果结果为true,执行{}中的语句体
3.如果结果为false,直接跳过if结构
双选泽|双分支 :else
双选泽|双分支 :
if(boolean表达式){ 语句体1; }else{ 语句体2; }
执行流程 :
1.boolean表达式,得到boolean结果
2.如果结果为true,执行{}中的语句体1
3.如果结果为false,执行else后的语句体2
多选泽|多分支 : else if
多选泽|多分支 :
if(boolean表达式1){ 语句体1; }else if(boolean表达式2){ 语句体2; }else if(boolean表达式3){ 语句体3; }.... else{ 语句体n;}
1.boolean表达式1,得到boolean结果,如果结果为true,执行{}中的语句体1
2.如果结果为false,执行boolean表达式2,如果结果为true,执行{}中的语句体2
3.如果结果为false,执行boolean表达式3,如果结果为true,执行{}中的语句体3
…
4.如果以上都不满足,执行else后的语句体n;\
注意: 一个if…else为一个结构,只能执行一个语句体
(如果{}中的语句体只有一句,前后的{}可以省略)
————————————————————————————————
7—1、2 if三目运算
对于有些选择分支结构,可以使用简单的条件运算符来代替. 如:
if(a<b) min=a; else min=b;
可以用下面的条件运算符来处理
min=(a<b)?a:b;
其中"(a<b)?a:b"是一个"条件表达式",它是这样执行的: 如果a<b为真,则表达式取a值,否则取b值.
条件运算符由两个符号组成"?“和”:", 要求有3个操作对象,所以也叫它三目运算符
它的一般形式为:
表达式1?表达式2:表达式3;
————————————————————————————————
7—2、0 switch定值判断
switch 定值判断
语法 : switch(条件){ case 值1: 语句体1; break; case 值2: 语句体2; break; ..... default: 语句体n; break; }
条件 : 变量 ,表达式 数据类型 : byte short int char 枚举(jdk1.5) String(jdk1.7) case : case跟定值,要与条件的结果判断,条件 的结果如果与case后的定值 相等就指定对应的语句体
break : 结束当前switch语句,防止case穿透 default : 相当于else,可以定义可以不定义 位置 可以定义
在switch语句 中的任意位置条件 : 变量 ,表达式
数据类型 : byte short int char 枚举(jdk1.5) String(jdk1.7)
case : case跟定值,要与条件的结果判断,条件 的结果如果与case后的定值 相等就指定对应的语句体
break : 结束当前switch语句,防止case穿透
default : 相当于else,可以定义可以不定义(位置 可以定义 在switch语句 中的任意位置)
————————————————————————————————
7—2、1 lambda表达式
lambda表达式
本质是一个函数:
一般的函数类如下:
有返回值,方法名,参数列表,方法体
int add(int a , int b ){
return a+b
}
lambda表达式的话,只有参数列表,方法体
(参数 列表)->{方法体}
()用来描述参数列表
{ } 用来描述方法体
-> 是lambda运算符,箭头运算符
lambda表达式
cal c = (int a, int b) -> {
return a + b;
};
精简代码:
cal c = (a,b) -> a + b;
Lambda表达式精简语法
1、参数类型可以省略
2、假如只有一个参数,()可以省略
3、如果方法体只有一个语句{ }可以省略
4、如果方法体唯一的语句是return返回语句,那么{ }和return要同时省略
lambda表达式,实现接口方法
*/
public class Por {
public static void main(String[] args) {
方法重写实现接口方法1
cal cc=new cal() {
@Override
public int add(int a, int b) {
return a+b;
}
};
System.out.println(cc.add(1,2));
--------------------------------------------------------------------
lambda表达式,实现接口的方法2
cal c = (int a, int b) -> {
return a + b;
};
System.out.println(c.add(2,9));
}
public interface cal {
int add(int a, int b);
}
}
lambda表达式静态引用
1、lambda表达式方法引用 如果lambda表达式方法体已经有其他方法/现那么则可以使用
方法引用
2、静态方法引用 类名::方法名
3、实例方法引用 实例名::方法名 构造方法引用:
4、无参构造方法引用 类名::new
5、有参构造方法引用 实例名 ::new
————————————————————————————————
7—2、2 yield???
————————————————————————————————
8、循环结构
————————————————————————————————
8—1、0 while
while 循环 while是最基本的循环,它的结构为:
while( 布尔表达式 ) { //循环内容 } 只要布尔表达式为 true,循环就会一直执行下去。
实例 Test.java 文件代码:
public class Test { public static void main(String[] args) {
int x = 10;
while( x < 20 ) { /·循环条件
System.out.print("value of x : " + x );/·循环内容
x++; /·循环次数
System.out.print("\n");
} } }
————————————————————————————————
8—1、1do while
do…while 循环 对于 while 语句而言,如果不满足条件,则不能进入循环。但有时候我们需要即使不满足条件,也至少执行一次。
do…while 循环和 while 循环相似,不同的是,do…while 循环至少会执行一次。
do { //代码语句 }while(布尔表达式);
注意:布尔表达式在循环体的后面,所以语句块在检测布尔表达式之前已经执行了。 如果布尔表达式的值为 true,则语句块一直执行,直到布尔表达式的值为 false。
实例 Test.java 文件代码:
public class Test {
public static void main(String[] args){
int x = 10;
//先输出一次
do{
System.out.print("value of x : " + x );
x++;
System.out.print("\n");
//符合条件在进行循环
}while( x < 20 );
}
}
————————————————————————————————
8—2、0 for循环
for循环执行的次数是在执行前就确定的。语法格式如下:
for(初始化; 布尔表达式; 更新) { //循环内容 }
关于 for 循环有以下几点说明:
最先执行初始化步骤。
1、可以声明一种类型,但可初始化一个或多个循环控制变量,也可以是空语句。
2、然后,检测布尔表达式的值。如果为 true,循环体被执行。
如果为false,循环终止,开始执行循环体后面的语句。
3、执行一次循环后,更新循环控制变量。
再次检测布尔表达式。循环执行上面的过程。
public class Test {
public static void main(String[] args) {
//先声明,后判断是不是ture,在自增
for(int x = 10; x < 20; x++) {
System.out.print("循环次数: " + x );
System.out.print("\n");
}
}
}
————————————————————————————————
8—2、1增强 for 循环(foreach)
语法:
for(声明语句 : 表达式) { //代码句子 }
声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。
表达式:表达式是要访问的数组名,或者是返回值为数组的方法。
public class Demo01 {
public static void main(String[] args){
int[] numArray=new int[5];
for (int index = 0; index < numArray.length;index++){
numArray[index] = index+1;
}
//(数据类型 声明变量:要遍历的内容),数据类型与:号后的类型一致
for(int number : numArray){
System.out.println(number);
}
}
}
break 关键字
break 关键字 break 主要用在循环语句或者 switch 语句中,用来跳出整个语句块。
break 跳出最里层的循环,并且继续执行该循环下面的语句。
continue 关键字
continue 关键字 continue 适用于任何循环控制结构中。作用是让程序立刻跳转到下一次循环的迭代。
在 for 循环中,continue 语句使程序立即跳转到更新语句。
在 while 或者 do…while 循环中,程序立即跳转到布尔表达式的判断语句。
public class Test {
public static void main(String[] args) {
int [] numbers = {10, 20, 30, 40, 50};
for(int x : numbers ) {
//在当x等于30时停止当次循环
if( x == 30 ) {
continue;
}
System.out.print( x );
System.out.print("\n");
}
}
}
————————————————————————————————
9、数组
1一维数组
在java中数组被看成是一个对象
在定义数组时,有两种定义方法:int[] a 和int a[];第二种是C/C++对数组定义方式,对于JAVA建议采用第一种定义方式。
总的原则:任何对象在被调用之前必须先被初始化!
1 一维数组的定义
//定义包含三个元素的一维数组 //方法1,先new对象,然后再初始化每个元素 int[] a = new int[3]; a[0] = 1; a[1] = 2; a[2] = 3;
方法一要注意的是不能这样写:
int[] a = new int[3]; a = {1,2,3};
原因是用new int[3]这种方式创建对象,对象已经被初始化并赋初值为0;
//方法2,直接赋初值来创建对象
int[] b = {1,2,3};
//方法3,new完对象直接初始化
int[] c = new int[]{1,2,3};
方法三要注意的是不能这样写: int[] c = new int[3]{1,2,3};
即这种方法不能指定维度,原因:如果指定了数组初始化操作,则不能定义维表达式。
注意:如果用new定义数组时,必须指定其维度,这样定义是错误的: int[] d = new int[];
如果无法确定其元素个数,可以这样定义:int[] e = {};
2 二维数组
2 二维数组的定义
基本与一维数组类似
//定义一个3行5列的二维数组
//方法1,先new对象,然后再初始化每个元素
int[][] a = new int[3][5]; a[0][0]=1; a[0][1]=2; a[0][2]=3;
//方法2,直接赋初值来创建对象
int[][] b = {{1,1,1,1,1}, {2,2,2,2,2}, {3,3,3,3,3} };
//方法3,new完对象直接初始化
int[][] a = new int[][] {{1,1,1,1,1}, {2,2,2,2,2}, {3,3,3,3,3} };
定义二维数组必须指定其行数,列数可以指定,可以不指定。
这样定义是正确的:
int[][] d = new int[3][];
这样定义是错误的:
int[][] d = new int[][4]; int[][] d = new int[][];
也可以定义不规则数组:
arr = new int[2][];
arr[0] = new int[3]; arr[1] = new int[5];
数组的长度
length是数组的一个属性(不是方法!),对于一维数组int[] b = {1,2,3}; b.length的值是3
————————————————————————————————
10、数组拷贝???
11、数组扩容???
————————————————————————————————
12、方法
方法的定义 一般情况下,定义一个方法包含以下语法:
修饰符 返回值类型 方法名(参数类型 参数名){ ... 方法体 ... return 返回值; }
方法包含一个方法头和一个方法体。下面是一个方法的所有部分:
修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。 返回值类型
:方法可能会返回值。returnValueType
是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void。
方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
方法体:方法体包含具体的语句,定义该方法的功能。
————————————————————————————————
1静态方法
静态方法(或称为类方法),指被 static 修饰的成员方法,静态方法中只能调用静态成员或者方法,不能调用非静态方法或者非静态成员
静态方法只能访问静态方法和静态成员。
class Test{
public static int sum(int a,int b){//加入static关键字,变成静态方法
return a+b;
}
public static void main(String[] args){
int result=sum(1,2);//静态方法调用静态方法
System.out.println("result="+result);
}
}
静态方法与实例方法的区别如下: 静态方法不需要通过它所属的类的任何实例就可以被调用,因此在静态方法中不能使 this关键字,也不能直接访问所属类的实例变量和实例方法,但是可以直接访问所属类的静态变量和静态方法。另外,和 this 关键字一样
super 关键字也与类的特定实例相关,所以在静态方法中也不能使用 super 关键字。
————————————————————————————————
1实例方法
非静态方法既可以调用静态成员或者方法,又可以调用其他的非静态成员或者方法。在实例方法中可以直接访问所属类的静态变量、静态方法、实例变量和实例方法。
非静态方法要被实例化才能被静态方法调用。
class Test{
public int sum(int a,int b){
return a+b;
}
public static void main(String[] args){
Test test=new Test();//实例化类
int result=test.sum(1,2);//调用非静态方法
System.out.println("result="+result);
}
}
————————————————————————————————
3、方法重载
如果有两个方法的方法名相同,但参数不一致,那么可以说一个方法是另一个方法的重载。
方法名相同
1、方法的参数类型
2、方法的参数个不一样 ,位置不一样
3、方法的返回类型可以不相同
4、方法的修饰符可以不相同
5、 main 方法也可以被重载
1.在同一个类中
方法名必须相同,方法的参数类不同 (和返回值类型没有关系)
public class A {
int a=1;
int b=2;
int h;
A() {//无参构造方法
System.out.println("无参数构造函数");
}
A(int i) {//有参构造方法
System.out.println("房子高度为 " + (i + a)+" 米");
h = i;
}
void info() {//无参有返回值方法
System.out.println("房子高度为 " + (h + b)+" 米");
}
void info(int c) {//有参数
System.out.println(c+"" +
"个房子高度为 " + (a +b)+" 米");
}
void info(String s) {//类型不同
System.out.println(s + ": 房子高度为 " + (h + a+b)+" 米");
}
public static void main(String[] args) {
A t = new A(3);
t.info();
t.info(2);
t.info("重载方法");
//重载构造函数
new A();
}
}
说明: 参数列表不同包括:个数不同、类型不同和顺序不同。 仅仅参数变量名称不同是不可以的。 跟成员方法一样,构造方法(构造器)也可以重载。
声明为final的方法不能被重载。 声明为static的方法不能被重载,但是能够被再次声明。
————————————————————————————————
————————————————————————————————
结束
第二阶段
面向对象
第三阶段
数据结构
集合
StreamAPI
第四阶段
字符串
反射
自定义注解
日期类
第五阶段
IO
BIO
NIO
AIO
xml
JSON
MVC
单例模式
单例工厂
多线程
Socket
问题1,lambda,yield不会,数组拷贝, 数组扩容