关键字
标识符
就是给类/包/变量 取的名称
语法: 1.不能与关键字同名 2.只能以_或者$或者大小写开头,后面可以跟_或者$或者大小写字母或者数字
但是如果你写了中文在标识符中也不会报错,不建议这样写
变量
变量就是计算机内存中一块存储空间
数据类型
基本数据类型
数字类型
整型
byte
short
int
long
浮点型
double
float
字符类型
char
布尔类型
boolean
引用类型
String
运算符
常见的数学运算符
+ - * / % ......
++与--
a++:先赋值,再自增
++a:先自增,再赋值
复合运算符
a += 值; 效果: a = a + 值
a -= 值; 效果: a = a - 值
a *= 值; 效果: a = a * 值
比较运算符
== :比较左边与右边的值是否相等,如果相等结果true. 否则返回false
!= :比较左边与右边的值是否不相等,如果不相等返回true.否则返回false
> >= < <=.....
逻辑运算符
& :并且 效果:连接两个条件,如果两个条件都成立,则整体成立
| : 或者 效果:连接两个条件,如果两个条件都不成立,则整体不成立
! : 取反 效果:本身的值是true,使用了取反符号就变成false
&& : 双与 也表示并且,但是带短路效果
|| : 双或 也表示或者,但是带短路效果
位运算符
& :如果连接的是boolean表达式,则充当逻辑运算符 如果连接的是整数,则充当位运算 符 将两个数字的二进制形式,每一位都进行运算,如果两个数字都是1,则结果为1 否则结果为0
| :如果连接的是boolean表达式,则充当逻辑运算符 如果连接的是整数,则充当位运算符 将两个数字的二进制形式,每一位都进行运算,如果两个数字有一个是1,则结果为1 否则结果为0
^ : 将两个数字的二进制形式,每一位都进行运算,如果两个数字不相等,则结果为1 否则结果为0
>> :右移 将指定整型的二进制数向右边移动指定的位数。 右边移动的数字就丢失,左边会空出位置出来,如果符号位是1则左边填1,如果符号位是0,则左边填0
<< : 左移 将指定整型的二进制数向做边移动指定的位数。 左边移动的数字就丢失,右边会空出位置出来,空出的位置填0
>>> :无符号右移 将指定整型的二进制数向右边移动指定的位数。 右边移动的数字就丢失,左边会空出位置出来,空出的位置填0
三目运算符
boolean表达式?java代码1:java代码2
特点:如果boolean表达式的值为true,则执行java代码1,否则执行java代码2
选择结构
if语句
switch语句
switch(变量){
case 值:
java代码块;
break;
case 值:
java代码块;
breka;
...
[default:java代码块;]
}
效果:
从第一个case开始进行判断(使用case后的值与switch中的变量进行比较是否相等),如果相等,则执行该case后面的java代码块,然后结束整个switch结构
如果不相等,则跳掉下一个case进行比较
如果所有的case都不相等,则执行default后面的代码块
细节问题:
1.switch后跟的变量的数据类型
只能接受:char byte short int String
Character Byte Short Integer enum
2.break可以省略
break的作用:结束switch结构
所以如果执行的case后面没有break,则会自动的往下执行(下面的case不判断,直接执 行),直到遇到break,或者所有代码执行完才结束switch结构
3.default也可以不放在最后
如果default没有放在最后,则default中也需要添加break,否则会不判断就执行default下面的case
循环结构
for循环
While循环
while(条件){
循环体;
}
只要条件成立,就执行一次循环体。直到条件不成立
do-while循环
do{
代码块;
}while(条件)
先执行代码块,再判断条件。 条件成立,继续循环。 条件不成立,循环结束
特点:代码块至少会执行一次
break continue return
这三个关键字都可以在循环体中使用
break:结束当前循环
continue:结束本次循环,并立即开始下一次循环
return:结束当前方法
注意:
return:可以写在任何一个方法中
break与continue,在嵌套循环中,只能结束当前的那一层循环
方法
修饰符 返回值类型 方法名(形参列表){
方法体;
}
返回值类型:
返回值: 方法相当于程序的功能,那么返回值就是通过调用这个功能得到的东西
例如: 请小a同学帮我去买一瓶水 ----》 相当于我调用小a同学的购物功能
结果: 我通过调用这个功能 我得到了一瓶水
在这个案例中,这瓶水就是返回值
同时也有可能调用了一个功能却得不到任何东西。 比如:我请小a出去 ---》 相当于调用小a的行走功能
结果:我通过调用这个功能,什么也没有得到
就说明:行走功能是没有返回值的
在java中得到的任何东西都是数据,只要是数据就一定有类型
那么我们在设计方法时,就必须设计好返回什么数据给调用方法的人,然后将这个数据的类型写在定义方法的地方
特定的类型:void 表示没有返回值
注意:
所有的方法之间都是独立的,所以千万不要将一个方法定义在另一个方法的方法体中
方法的重载
方法的重载: 在同一个类中,多个方法的方法名一致,但是形参列表不一致 。
形参列表不一致:
1.类型不一致
2.数量不一致
3.顺序不一致
以上三个条件,满足了任意一个,都形成方法的重载
数组
动态初始化
只声明数组的长度,而不给数组的元素赋值
数据类型[] 变量名 = new 数据类型[长度];
静态初始化
声明数组的长度的同时也指定每一个元素的值
数据类型[] 变量名 = new 数据类型[]{数据1,数据2....};
也可以简写为: 数据类型[] 变量名 = {数据1,数据2....};
注意:这个简写只对初始化有效
二维数组
动态初始化:
数据类型[][] 变量名 = new 数据类型[m][n];
m:表示创建的外层数组的长度
n:表示创建的内层数组的长度
注意:n可以省略
如果指定n,则会初始化内层数组,默认元素为对应类型的默认值
如果没有指定n,则只会初始化外层数组,不会初始化内层数组
静态初始化:
数据类型[][] 数组名 = new 数据类型[][]{{...},{....},{...}....};
可以简写为:(只在初始化时有效)
数据类型[][] 数组名 = {{...},{....},{...}....};
数组相关的工具类
Arrays类
toString方法
将指定数组的所用元素解析为字符串
String str = Arrays.toString(数组);
copyOf方法
此方法可以帮我们创建新的指定长度的数组,并且会自动的帮我们为新数组复制元素
数组名 = Arrays.copyOf(原数组,新数组的长度);
效果:copyOf方法创建了一个长度是 新数组的长度 的新数组,
然后自动的将原数组的所有元素复制到新数组中
该方法返回新数组
System类
arraycopy方法
使用copyOf方法时,默认都是从原数组的第一个元素开始赋值
而此方法则可以指定复制的位置
arraycopy(原数组,开始复制的索引,目标数组,开始粘贴的索引,复制的元素的个数)
数组元素的排序
冒泡排序
就是从第一个元素开始,与后一个元素两两比较,
如果前面的元素大于了后面的元素,则这两个元素交换位置
可变长参数
定义的方式:数据类型... 变量名
注意事项
1.使用了可变长参数,则数据类型就统一了
2.可变长参数可以与其他参数一起使用,但是可变长参数只能在最后
3.一个方法只能有一个可变长参数
面向对象
类 与 对象
类:具备相同属性与方法的对象的集合
其实就是一个种类的抽象,所以类本质上就是表示一个种类/分类
对象:表示某一个具体的事物(一定属于某一个类)
创建对象
new 类名();//匿名对象
类名 变量名 = new 类名();//将指定对象赋值给变量
我们创建的每一个class,都是一个类型(引用类型)
引用类型:存的值是地址值
给属性赋值:
对象名.属性名 = 值;
取出对象的属性:
对象名.属性名
调用对象的方法:
对象名.方法名(实参列表)
全局变量 与 局部变量
全局变量:定义在类中的变量
我们定义的属性其实就是全局变量
局部变量:定义在方法中的变量
特点:
全局变量:整个类中都可以使用
局部变量:只能在定义的方法中使用
全局变量与局部变量可以同名
那么在使用变量时,根据就近原则决定使用的是哪一个变量
就近原则:现在当前方法中找,如果找到了就直接使用该变量。
如果找不到去类中找,如果找不到就报错
全局变量(属于对象)会自动的初始化
局部变量不会自动的初始化
对象的生命周期
生命周期:从出生到死亡的全过程
出生:被new出来的时候,就开始生命周期
销毁:JVM包含了一个GC(垃圾回收器)的工具,GC会不定时去检查有没有垃圾
如果一个对象没有被引用,则会被认为是垃圾,就可能会被回收
构造方法
构造方法是一个类中的特殊方法
作用:用来创建对象
我们之前创建对象的写法:new 类名(),其实就是在调用构造方法
如果一个类没有自定义构造方法,则java会为该类自动生成一个无参构造方法 但是如果我们自定义了构造方法,则java就不会为我们自动生成该无参构造方法了
代码块
局部代码块:
特点:在该代码块中声明的变量,生命周期就只属于该代码块
构造代码块:
特点:每次调用构造方法,会先执行构造代码块中的代码再执行构造方法中的代码
构造代码块的原理: java会自动的将构造代码块中的代码优化到每一个构造方法中的最前面,所以调用构造方法一定会先执 行构造代码的代码
静态代码块:
定义在类中:
static{代码...}
特点:在加载类信息的时候执行一次
实际开发中经常使用静态代码块做程序的初始化操作
继承
继承的意义: 减少重复代码
继承的语法 : 修饰符 class 类名 extends 父类的类名{}
继承的注意事项:
1.构造方法不能被继承
2.java是单继承的语言 一个子类只能有一个直接父类
3.支持多重继承 a 继承 b,b 继承 c
4.private修饰的资源可以被继承,但是继承之后不能使用
5.继承是针对对象而言的 所以如果资源使用static修饰,就不无所谓是否是继承了
多态
多态:就是 变态
就是说 一个变量 在编译期 的状态 与在运行期的状态是不一致的 编译期:将.java文件编译成.class文件的过程
运行期:就是执行这个程序的过程
状态:就是类型
编译期Java如何确定一个变量的类型:就是看定义变量是变量名前面的类型
运行期Java如何确定一个变量的类型:就是看该变量存放的地址值执行的对象的类型
比如:
class Fu{}
class Zi extends Fu{}
Fu f = new Zi();
在编译期:java认为f是Fu类型 在运行期:java认为f是Zi类型 这行代码就形成了多态,形成多态的代码不会编译错误
多态中的方法重写:
口诀: 编译看左边,运行看右边
多态中属性的问题:
口诀:编译看左边,运行看左边
类型转换
多态本质就是类型转换
类型转换的口诀:
小转大,自动转
大转小,强制转
大小的标准:
如果是基本数据类型:整型--->根据占用内存的大小
浮点型-->根据占用内存的大小
整型与浮点型---->浮点型大于整型
如果是引用类型:父类大于子类
如果两个类没有继承关系,就不能类型转换,否则会出现ClassCastException
抽象类
使用abstract修饰的类
特点:既可以定义普通方法也可以定义抽象方法
抽象方法:使用abstract修饰,只有方法定义没有方法体的方法
抽象类的主要特点就是体现在抽象方法中,所以创建抽象类的目的应该是为了声明抽象方法 也就是说重点是抽象方法
那么抽象方法有什么意义呢?
抽象方法的意义体现在当前抽象类的子类中
抽象类的其他细节 :
1.抽象类不能实例化
2.抽象类可以声明构造方法
3.抽象类可以没有抽象方法(从逻辑上来说,没有抽象方法的抽象类是没有意义的)
4.抽象类的继承问题
抽象类 可以继承 普通类
意义:该抽象类就直接继承了该普通类的所有属性与普通方法
抽象类1 可以继承 抽象类2
意义: 抽象类1继承了抽象类2中的所有方法包括抽象方法
抽象类1的子类就需要重写这两个抽象类中的所有抽象方法
注意:抽象类1可以选择直接继承抽象类2的抽象方法
抽象类1可以选择直接继承抽象类2的抽象方法
5.抽象类/方法的修饰符的问题 abstract与final修饰符不能共存
内部类
局部内部类:
如果在某个方法中需要使用一个类 并且这个类只会在该方法中使用
则可以在该方法直接声明该类 这个类就是局部内部类
成员内部类
如果一个类只会被另一个类使用,并且可能在该类的多个位置使用
建议将这个类声明为成员内部类
静态内部类
如果一个类只会被另一个类使用,并且希望加载另一个类的时候就将该类加载出来
则可以使用静态内部类
匿名内部类
new 父类/接口(){ 类的定义 };
效果:
1.声明指定的类/接口的子类/实现类,但是这个类没有名称
2.创建该类的对象
注意:要写匿名内部类,必须指定该类的父类/接口
先写到这吧