Java SE学习笔记

Java笔记

Day01

编写第一个Java程序HelloWorld

public class HelloWorld{
    public static void main(String[] args){
        System.out.println("Hello world!!!");
    }
}

编码格式

ANSI GBK UTF-8

注释

使用场景
1.解释说明(提高代码的可读性)
2.注释无用代码
Java代码的注释分类
1.单行注释
//
2.多行注释
/*
*/
3.文档注释
/**
*/

输出

概念
给控制台显示内容
语法
1.System.out.print();//不换行()不能为空
2.System.out.println();//自动换行()可以为空

数据类型

数据类型
1.基本数据类型
	整数型:
		byte         1个字节
		short		 2个字节
		int			 4个字节		默认
		long		 8个字节		加L
	浮点型:
		float		 4个字节		加F
		double		 8个字节		默认
	布尔型:
		Boolean		 true   false
	字符型:
		char		 2个字节  
2.引用数据类型
	所有类的对象,都属于引用数据类型,引用数据类型有无数种
数据类型转换
1.小类型转大类型
	自动转换
2.大类型转小类型
	强制转换   (强转类型)数据
3.布尔不参与转换

标识符,关键字,保留字

标识符
名称:类名,变量名,接口名,枚举名,注解名,对象名,包名,方法名,属性名...
所有的标识符都是自定义的
命名规则(潜规则):
	类名,接口名,枚举名,注解名:大驼峰
		大驼峰:每个单词是的首字母大写
	变量名,对象名,方法名
		小驼峰:
			如果只有一个单词作为名称,那么该单词首字母小写
			如果有多个单词作为名称,第一个单词首字母小写,其他单词首字母大写
	包名
		全小写
	常量名
		全大写

注意:
	1,做到见名知意
	2,不要使用数字开头
	3,不要使用特殊字符,建议不要使用中文
	4,特殊字符_与$可以使用
	5,包名的命名潜规则:
		com.公司名称缩写.包名
		如:
			com.qf.demo
		com.项目名称.包名
		如:
			com.weixin.shiti
	6,全大写时使用单词之间使用下划线连接
	7,不能使用关键字或保留字进行命名
关键字
Java中具有特殊意义的单词
public
static
void
保留字
Java中目前没有特殊意义的单词,但不能使用,以后的java发展过程中可能会作为关键字使用

Day03

变量

概念
记录一个可以被改变的值
使用
1,声明
	语法:数据类型 变量名;
	注意:
		1,同一个作用域下变量名不能重复
		2,只能在方法中声明,main函数(main方法)
	特殊情况(了解):
		一次可以声明多个数据类型相同的变量
		语法:
		数据类型 变量名1,变量名2,变量名3,...;
2,赋值
	语法:变量名 = 值;
	特殊情况:声明并赋值
		语法:数据类型 变量名 = 值;
	注意:
		一个变量可以多次赋值
3,使用
	直接使用变量名
	
注意:
	初始化:变量的第一次赋值,称为变量的初始化
	作用域:变量声明时,所在的大括号中可以使用
练习
public class Woman{
	public static void main(String[] args){
		String name = "狗蛋"; 
		String xingbie = "女"; 
		String FS = "黑";
		int age =18;
		System.out.println("姓名:"+name+"\n性别:"+xingbie+"\n年龄:"+age+"\n肤色:"+FS);
		name="大漂亮";FS="白";
		System.out.println("狗蛋觉得自己太丑了,于是她就去整容了");
		System.out.println("姓名:"+name+"\n性别:"+xingbie+"\n年龄:"+age+"\n肤色:"+FS);
		
	}
}

转义字符

概念:转义字符是形式文法的一部分

常用的转义字符:
	\"	表示内容的双引号
	\'	表示内容的单引号
	\\	表示内容的反斜杠
	\n	换行
	\t	制表
这种转义字符,虽然在形式上由两个字符组成,但只代表一个字符.

运算符

算数运算符
+,-,*,/,%(取余)
++:自增
	++在前
			1,自增
			2,参与运算
		从运行效率的角度考虑++在前的运行速度高一些
	++在后
			1,存值
			2,使用自己+1
			3,使用存值进行运算
	
--:递减
	--在前:
		总结:先递减,在参与运算
	--在后:
		总结:先参与运算,在递减
(++4+3+(3--))=11     加括号已没有用,存值,是自己-1,使用存值进行运算.
逻辑运算符
<:小于
<=:小于等于
>:大于
>=:大于等于
==:判断是否相等
	==可以判断基本数据类型值是否相同
	==可以判断引用数据类型地址是否相同(了解)
!=:判断是否不相同

&&:短路与			   同真为真
||:短路或				有真为真
!:非					非真为假,非假为真
赋值运算符
=:将等号右边的值赋值给左边的变量
+=:加等
-=:减等
*=:乘等
/=:除等
%=:除取余等
三目运算符
别名:三元运算符
	
语法格式:
	条件表达式?值1:值2;
	注意:当条件表达式值为true时,取值1,否则取值2

例子
	获取三个值中的最大值
	要求:使用三目运算符完成
	
	步骤
		1,定义三个变量记录值
			int a = 10;
			int b = 1;
			int c = 12;
		2,先获取a与b之间的最大值
			int max = a > b?a:b;
		3,使用步骤2的最大值与c进行比较,获取其最大值
			int overMax = max > c?max:c;
		注意:步骤2与步骤3合并
			int overMax = (a > b?a:b) > c ? (a > b?a:b) : c;
字符串连接符
+
在运算中出现字符串(String),此时+表示字符串连接符
注意:
	所有数据类型与字符串使用字符串连接符,结果都为字符串

	"123" + 1+ 2+ 3 = "123123"
	1+2+3+"123" = "6123";
位运算
前提转换为2进制
<<(开口朝向为移动方向,后面数值为移动次,从右边0)	
>>()	
&(同真为真)
|(有真为真)
^(相同为假,不同为真)

进制

2  	8 	10 	16
0b 	0		0x

键盘录入

对应的类:Scanner
使用步骤:
	1,导包 
		代码:import java.util.Scanner;
		书写位置:
			类上
	2,创建Scanner对象
		代码:Scanner 变量名 = new Scanner(System.in);
		书写位置:
			使用之前
	3,等待用户输入
		等待用户输入字符串:
			String 变量名2 = 步骤2的变量名.next();
		等待用户输入整形数字
			int 变量名3 = 步骤2的变量名.nextInt();
		书写位置:
			代码逻辑需要用户输入的使用

字符串内容的比较

语法:
	字符串的变量名或字符串.equals(要比较的字符串或字符串变量名)

例子:
	String str01 = "ss";
    String str02 = "mmm"
    boolean b = str01.equals(str02);

Day04:分支语句

Java中的语句分类

顺序语句
	代码从上向下依次执行
分支语句
	有多个选择,但是只能选择一条进行执行
循环语句

分支语句

if语句
1,基本的if语句
	语法:
		if(条件表达式){
			当条件表达式值为true时,执行的代码
		}

2,if else语句
	语法:
		if(条件表达式){
			当条件表达式值为true时,执行的代码
		}else{
			当条件表达式值为false时,执行的代码
		}
	
3,else if语句
	语法:
		if(条件表达式1){
			当条件表达式1为true时,执行此处代码
		}else if(条件表达式2){
			当条件表达式2为true时,执行此处代码
		}
		...
		else if(条件表达式n){
			当条件表达式n为true时,执行此处代码
		}else{
			当以上条件都不满足,执行此处代码
		}
		注意:
			else if可以有多个,也可以没有
			else可有可无
	
4,if的嵌套
	在if大括号中可以使用if
switch语句
语法:
	switch(变量){
		case 常量1:
		当变量值等于常量1时,执行此处代码
		break;
		case 常量2:
		当变量值等于常量2时,执行此处代码
		break;
		...
		case 常量n:
		当变量值等于常量n时,执行此处代码
		break;
		default:
		当变量值不等于以上常量时执行此处代码
		break;
	}
if与switch的区别
if可以判断区间,也可以判断值是否相同
if代码结构稍微有一点混乱

switch只能判断值是否相同
switch的语法稍微简单一些
switch的执行效率稍微高于if
switch的变量只能是基本数据类型或String,而且String是在jdk1.5及以后才支持

局部变量

概念:在方法中声明的变量,就是局部变量
注意:
	1,同一个作用域下,局部变量不能重名

Day05:循环

循环语句(重点)

作用
重复执行一段代码时
分类
while
do while
for
while
语法:
	while(条件表达式){
		当条件表达式为true时,执行此处代码
		此处代码执行完毕后,在此判断条件表达式
		如果表达式依然为true,继续执行此处代码
		如果表达式值为false,结束循环
	}
do while
语法:
	do{
		先执行此处代码,在判断条件表达式
		如果条件表达式值为true,再次执行此处代码
		否则结束循环
	}while(条件表达式);

	特点:循环体至少执行一次
	
与while的区别:
	1,do while先执行循环体,在判断条件表达式
	2,while先判断条件表达式,在执行循环体

for

语法:
	for(表达式1;条件表达式2;表达式3){
		循环体4
	}
	表达式1:初始化变量,只执行一次
	条件表达式2:循环条件
	表达式3:修改表达式1的变量的值
	循环体:要重复执行的代码
	
执行流程:
	1,2,4,3,2,4,3...2

随机数

作用:随机生成一个数字
使用:
	1,创建Random对象
	2,获取随机数
		方式1:随机获取一个int范围内的整数
		int 变量名 = random对象.nextInt();
		方式2:随机获取一个0~x范围内的整数
		int 变量名 = random对象.nextInt(x+1);

break与continue

流程控制语句

break:
	break在switch中使用,表示跳出当前代码块
	break在循环中,表示跳出当前循环
	break与标记结合使用,表示跳出指定代码块(了解)
	
continue:
	continue单独使用,表示跳过本次循环
	continue与标记结合,表示跳过标记所在的本次循环(了解)
	注意:只能在循环中使用
	
总结:break表示跳出当前循环,continue跳过本次循环

Day06:方法

方法

名词解释
函数:方法
作用
封装一段代码
优点
1.提高编写速度
2.降低代码耦合度
3.降低了代码的重复度
4.使代码方便使用
5.提高代码的阅读性
方法的定义
定义
	作用:制作方法
	位置:类中,方法以外
	分类:
		基本的方法
			public static void 方法名(){
				封装的代码
			}
			
		有参数的方法
			public static void 方法名(形参列表){
				方法体(封装的代码)
			}
			形参:声明的变量
			形参列表:多个声明的变量,多个变量之间使用逗号隔开
			
		有返回值的方法:
			public static 返回值类型 方法名(){
				方法体;
				return 返回值;
			}
			名词解释:
				返回值类型:返回的数据类型
				void:没有返回值(返回值为空(null))
				return:
					单独使用表示为方法结束
					return后有数值或变量,表示结束后方法,并返回该数值或变量或对应的数值
					注意:
						如果有返回值的方法使用分支语句作为结束
						要保证每一个分支都有返回值
						一个方法一次只能返回一个
						
		有参数又返回值的方法:
			public static 返回值类型 方法名(形参列表){
				方法体(封装的代码)
				return 返回值;
			}
方法的调用
作用:使用方法
位置:方法中(方法外不建议使用)
分类:
	调用基本方法
		语法:
			方法名();
			
	调用有参数的方法
		语法:
			方法名(实参列表);
		注意:调用有参数的方法,实参列表要与形参列表,顺序一致,数据类型一致
		
	调用有返值的方法
		语法:
			方法名();
			或
			数据类型 变量名 = 方法名();
	
	调用有返值有形参的方法
		语法:
			方法名(实参列表);
			或
			数据类型 变量名 = 方法名(实参列表);
		注意:
			如果调用方法有返回值,可以使用变量接收,也可以不接收
			接收的变量要与返回值的数据类型相同

总结:
	返回值类型:返回值得数据类型
        方法名:自定义,符合小驼峰命名法
        形参列表:一组声明的变量,可有可无
        return:
            单独使用时,表示结束方法
            如果return后有数值或变量,表示结束方法的同时,返回该数值或该变量对应的值
特殊情况
多重调用
	概念:方法A中调用方法B,B方法中调用方法C
	注意:避免死循环
重载(*)
	概念:在同一个类中,方法名相同,形参列表不同
递归
	概念:在方法A中调用方法A

Day07:数组

概念

存储一组数据类型相同的数据
数组中的名词:
	下标:又名索引,数据在数组中的位置,从0开始
	长度:数组可容纳数据的个数
	元素:数组中容纳的数据
特点:数组长度,不可变
数组的步骤:0.声明  1.创建  2.使用	
数组的语法
声明:
	数据类型[] 数组名;
	数据类型 数组名[];(不建议使用);

创建:
 	动态
 		数组名 = new 数据类型[数组长度];
 			注意:基本数据类型默认值为0,引用数据类型默认为null;
 		数组名 = new 数据类型[]{值1,值2,值3,...};
 			注意:创建时的值就是数组的长度
 			
 	特殊情况:声明并创建
 			数据类型[] 数组名 = new 数据类型[数组长度];
            数据类型[] 数组名 = new 数据类型[]{值1,值2,值3,...};
            
    静态
    	必须声明与创建同时进行
    		数据类型[] 数组名 = {值1,值2,值3,...};
           
数组的使用
改
	数组名[] = 值;
查
	获取单个元素
		数组名[下标];
	获取数组长度
		数组名.length
进阶使用
数组的遍历
	作用:将数组中的数据逐个取出
查找
拷贝
	作用:将老数组中的数据复制到新数组中
		1.创建一个新数组,要求新数组的长度等于老数组的长度
		2.遍历老数组
		3.将老数组中取出的值放在新数组对应的位置
扩容
	作用:将老数组中的数据复制到新数组中,新数组的长度大于老数组,将新数组赋值给老			数组
		1.创建一个新数组,要求新数组的长度大于老数组的长度
		2.遍历老数组
		3.将老数组中取出的值放在新数组对应的位置
		4.将新数组赋值给老数组
数组中常见异常
ArrayIndexOutOfBoundsException:数组下标越界异常
	原因:获取或修改数组中数据时,下标超出下标的取值范围
	下标取值范围:0~数组长度-1

NullPointerException:空指针异常
	原因:使用null调用了属性或方法
	解决方法:保证不要使用null调用属性或方法
foreach(增强for循环)
作用:遍历
	for(数据类型 变量名:要遍历的数组或集合){
	
	}
	数据类型:取出数据的数据类型
	变量名:获取到的数据
了解
new:在堆内存开辟一片内存地址
可变参数:
	解决的问题:形参数量固定的问题
	要求:一个方法只能用一个可变参数,而且只能用位于形参的尾部
	语法:数据类型... 变量名	
重点:有返回值的for循环电脑不能判断能否执行,所以外部也得有返回值

Day08:二维数组

概念

存放一维数组的数组,称为二维数组

声明 创建

声明
	数据类型[][] 数据名;


创建
	动态
		不带值
			数组名 = new 数据类型[二维数组中存放一维数组的个数][一维数组中的元素个数];
		带值
			数组名 = new 数据类型[][]{
				{值,值,值},
				{值,值,值,值,},
				{值,...},
				.....
			};
	
	静态(和一维数组相同声明创建同时进行)
		数据类型[][] 数组名 = {
				{值,值,值},
				{值,值,值,值,},
				{值,...},
				.....
			};

使用

修改
	1.修改二维数组中某个一维数组中的某个位置的值
		数组名[i][j] = 值;
		注意:
			i为一维数组在二维数组中的位置下标
			j为元素在一维数组中的位置
	2.修改二维数组中的一维数组
		数组名[i] = 新的一维数组;
			i为一维数组在二维数组中的位置下标
	3.修改整个二维数组
		数组名 = 新的二维数组;
		
查询
	1.查询二维数组中某个一维数组中的某个位置的值
		数组名[i][j]
		注意:
			i为一维数组在二维数组中的位置下标
			j为元素在一维数组中的位置
	2.查询二维数组中的一维数组
		数组名[i]
			i为一维数组在二维数组中的位置下标
	3.查询整个二维数组
		遍历
			思想:1,遍历二维数组2,获取二维数组中的一维数组
				3,遍历一维数组4,获取一维数组中的元素
	4.查询二维数组长度
		数组名.length(长度为二维数组中一维数组的个数)
		

算法(第三周周四)

概念
用代码完成数学公式就称为算法
评判算法是否优良
时间复杂度:执行该代码需要的时间,越短越好
空间复杂度:执行该代码需要的占据的运行内存,越少越好
优点
提高代码的执行效率
常见算法
两数交换
	int a = 10;
	int b = 1;
	int c = a;
	a = b;
	b = c;

寻找最值:
	寻找最大值(作业)
	寻找最小值
	寻找最大值下标(作业)
	寻找最小值下标

寻找指定的值:
	寻找指定值的位置
	寻找指定值是否存在

排序
	冒泡排序
	选择排序
	
二分查找

Day09

面向对象-基础(**)

面向过程
	特点:只考虑事物的发展顺序
	
面向对象
	特点:先考虑事务中存在那些对象,然后再建立对象与对象的关系
对象与类的关系
对象的概念
	现实生活中的对象:真实存在的事物
	java代码中的对象:用java代码描述现实生活中或虚拟世界的事物
类的概念:
	多个对象抽取其共同点形成的概念
如何创建一个类
	pubic class 类名{
	
	}
类中有什么?
	属性
		概念:多个对象提取的静态特征,如人的姓名,年龄,性别,肤色,身高等
		定义的位置:类中方法以外
		定义的语法:
			public 数据类型 属性名;
		又名:成员变量
		与变量的区别:
			1.作用域不同
			2.生命周期不同
			3.成员变量有默认值,基本数据类型默认为0,引用数据
			  类型为null局部变量无默认值
			4.成员变量有访问权限修饰符,局部变量没有访问权限修饰符
	
	方法
		概念:多个对象提取的动态(行为),如人的吃饭,睡觉等等
		定义的位置:类中方法以外
		定义的语法:
			public 返回值类型 方法名(形参列表){
				方法体
			}
		又名:函数,成员方法
       
    构造函数
    	概念:一个特殊的方法,该方法用户创建该类对象,使用new关键字调用
    	定义的位置:类中方法外
    	定义的语法:
    		public 构造函数名(形参列表){
    			方法体
    		}
    		注意:
    			构造函数名必须是类名,大小写都要一致
    			构造函数没有返回值
    			如果一个类中没有构造函数,系统将为其提供一个无参构造函数
    			如果一个类有构造函数,系统将不会为其提供构造函数
    			
    this:
    	概念:那个对象调用this所在的方法,this就代表谁
    	作用:
    		1.在本类中调用本类的属性或方法,该情况下this可以省略不写
    		2.如果局部变量与成员变量(属性)重名,可以用于区分成员变量与局部变量
    		3.在本类构造函数中调用本类其他构造函数,必须在构造函数的第一行,不能形成死循环  		
对象
如何创建对象?
	数据类型 对象名 = new 构造函数名(实参列表);
	简写
	类名 对象名 = new 类名(实参列表);
	注意:调用的构造函数所属的类,就是该对象的数据类型.属于引用数据类型
	
对象的创建过程
	1.使用new关键字在堆内存开辟一片内存地址
	2.给对象的属性赋初值,基本数据类型赋值为0,引用数据类型默认为null
	3.执行构造函数中的代码
	4.将栈的引用指向堆内存中的地址
	
如何使用对象调用它的属性
	修改对象的属性值:
		对象名.属性名 = 值;
	获取对象的属性值
		对象名.方法名(实参列表);
		
匿名对象:没有对象名的对象

Day10:面向对象的三大特征

继承

生活中的继承:
	晚辈继承长辈的物质或精神
代码中的继承:
	子类继承父类的所有属性与方法,构造函数除外
体现
语法
public class 子类名 extends 父类名{
	子类特有的属性
	子类特有的方法
}
子类
super关键字
	使用位置:子类中使用
	概念:谁调用super所在的方法,super就表示谁的父类对象
	场景:
		1.在子类构造函数中调用父类的构造函数
			语法:super(实参列表);
			注意:
				1.只能在构造函数第一行
				2.子类中没有明确写出调用父类构造函数,默认调用父类无参构造函数
		2.当子类属性名与父类属性名相同或子类重写父类方法时,在子类中调用父类属性或重写的方法,使用super调用
			语法:
				调用属性:super.属性名
				调用方法:super.方法名(实参列表);
父类
别名:基类,根类
情况:
	一个类如果没有明确的继承关系,那么默认继承于Object
	Object是所有类的父类
	
	class A{
		
	}
	class B extends A{
		
	}
	
	B是A的子类
	A是B的父类
	Object是A,B的父类(父类的父类也称为父类)
	Object是A的直接父类,是B的父类

		
Java的类只能单继承

封装

包装
	好处:1.保护内部  2.方便使用
封装的体现
变量:一个基本的变量封装一个值
数组:一个数组封装一组数据类型相同的数值
方法:封装着一段代码
类:封装多个属性,方法,构造函数...
对象:封装着多个属性值...
Java文件:封装着类
包:封装多个java文件
项目:封装多个包
...
访问权限修饰符
关键字				作用					  中文名
public			当前项目中都可用		   公共的
protected		同个包中或继承关系中可用	受保护的
默认的			  同个包可用				   默认的
private 		当前类中可用				私有的

可以修饰:属性,方法,构造函数,类(内部类)
包与导包
包:文件夹
	关键字:package
导包:
	A类与B类不在同一个文件夹下,B中使用A,此时需要在B中倒入A所在的包
	语法:
		import 包名.类名;
		import 包名.*;

多态

一个事物的多种形态

事:方法
物:对象
多态的体现
方法:
	重写
		要求:
			1.在继承关系中,子类方法与父类方法
			2.子类访问权限修饰符大于等于父类的访问权限修饰符
			3.返回值类型相同
			4.方法名相同
			5.形参列表相同
			6.方法体不同
			称为重写
	
	重载
		要求:
			1.同一个类中
			2.方法名相同
			3.形参列表不同
			称为重载
			
对象:
	子类对象转父类对象:自动转换
	父类对象转子类对象:强制转换
		可能会出现:ClassCastException(类型转换异常)
instanceof关键字
作用:判断该对象是否属于该类
注意:对象与类之间必须有继承关系
语法:
	boolean 变量名 = 对象名 instanceof 类名;

Day11:三大修饰符

final

含义:最终的,不可修改的
可以修饰:
	变量
		概念:final修饰的变量称为常量
		注意:
			1.final修饰的变量,值不被修改
			2.final修饰的局部变量只能赋值一次
			3.final修饰的属性必须赋值
			4.final修饰的变量名要求全大写(潜规则)
		语法:
			final 数据类型 常量名;
			访问权限修饰符 final 数据类型 常量名;
			
	方法
		概念:final修饰的方法不能被重写
		语法:
			访问权限修饰符 final 返回值类型 方法名(形参列表){
				方法体
			}
			
	类
		概念:final修饰的类不能被继承
		语法:
			访问权限修饰符 final class 类名{
				属性
				方法
				构造函数
			}

abstract

含义:抽象的
可以修饰:
	方法:抽象方法
		注意:
			1.抽象方法没有方法体
			2.有抽象方法的类一定是抽象类
		语法:
			访问权限修饰符 abstract 返回值类型 方法名(形参列表);
			
	
	类:抽象类
		注意:
			1.抽象类中不一定有抽象方法
			2.抽象类不能直接创建对象
			3.子类继承与抽象类,要么子类也是抽象类,要不重写父类中所有的抽象方法
		语法:
			访问权限修饰符 abstract class 类名{
				属性
				方法
				构造函数
			}
注意:abstract与final不能同时使用

代码块

语法:
	{
		方法体
	}
调用:
	创建该类对象时,由JVM调用
注意:
	在构造函数执行被调用

类加载

class文件运行时步骤
	1.加载class文件(字节码文件)类加载
	2.运行代码
	
类的加载时机:
	1.该类对象第一次创建时
	2.获取该类的类对象时
	3.第一次使用类名调用该类的静态属性或方法时
	...

static

含义:静态的(static修饰的内容属于该类)
可以修饰:
	属性:静态属性
		特点:属于该类的所有对象
		语法:
			访问权限修饰符 static 数据类型 属性名;
		调用方式:
			类名.属性名   或   对象名.属性名
			
		静态属性与非静态属性的区别
			静态属性属于该类的所有对象
			非静态属性属于该类的对象
			静态属性可以使用类名或对象名调用
			非静态属性只能使用对象名调用
			静态属性在类加载时就被初始化了
			非静态属性在对象创建时被初始化
			
			
	方法:静态方法
		注意:
			1.静态方法中不能使用this或super
			2.静态方法中不能直接使用非静态属性或方法
		特点:
			1.静态方法可以使用类名直接调用,也可以使用对象名调用
			类名调用语法:
				类名.方法名(实参列表);
			对象名调用语法:
				对象名.方法名(实参列表);
			2.静态方法可以被继承,但不能被重写
		语法:
			访问权限修饰符 static 返回值类型 方法名(形参列表){
				方法体
			}
		静态方法与非静态方法的区别:
			静态方法可以使用类名直接调用或使用对象名调用
			非静态方法只能使用对象名调用
			静态方法中不能使用this或super
			非静态方法中可以使用this或super
			静态方法中不能直接使用非静态成员(属性或方法)
			非静态方法中可以直接使用非静态成员和静态成员
			
			
	代码块:静态代码块
		特点:在类加载时被调用
		语法:
			static{
				方法体
			}
		注意:静态代码块只在类加载时被执行一次
		静态代码块与代码块的区别:
			静态代码块在类加载时被调用一次
			代码块在对象创建时调用,每次对象创建都会被调用
			
	内部类(暂时省略)

Day12:接口

定义

微观理解:	功能
宏观理解:	规则

语法:
	访问权限修饰符 interface 接口名{
	
	}
可以定义:
	公共静态常量
	公共静态方法
	公共抽象方法
	default修饰的方法
特点:
	接口中的属性的默认使用public static final修饰
	接口中的抽象方法默认使用public abstract修饰

接口的使用

接口使用接口
关系:一个接口可以继承多个接口
语法:
	访问权限修饰符 interface 子接口名 extends 父接口1,父接口2,...{
	
	}
类使用接口
关系:一个接口可以实现多个接口
语法:
	访问权限修饰符 class 类名 implements 接口1,接口2,..{
	
	}
注意
子类或子接口,可以继承父接口的公共静态常量,公共抽象方法,但是没有继承公共静态方法
子类对象转换为父类对象时,该父类对象无法调用子类特有的属性与方法,只能调用父类中定义的属性与方法
子类对象转换为父类对象时,该父类对象调用重写后的方法,调用的是子类重写后的方法

接口与抽象类的区别

不同点:
	接口:
		含义是功能或者规则
		有公共静态常量,公共静态方法,公共抽象方法
		子类可以实现多个接口
		接口可以继承多个接口
		
		
	抽象类:
		含义是概念
		有属性,构造函数,方法,代码块
		子类只能继承一个父类
		只能实现多个接口
共同点:
	1.都会生成class文件
	2.都无法直接创建对象
	3.都可以拥有抽象方法

接口回调(*)

案例1:按钮点击后执行欢迎语句
	分析:
		按钮:类
		点击:接口
案例2:
	类
        电脑
            USB接口1
            USB接口2
            USB接口3
            开机
            关机
        键盘
        	连接
        	断开连接
        	
        鼠标
        	连接
        	断开连接
        U盘
        	连接
        	断开连接
        	
        扩展器
        	连接
        	断开连接
    接口
        USB规则
            连接
            断开连接
案例3:
	台灯与灯泡
	接口:
		发光
	类:
		灯泡	实现发光的接口
		台灯
			属性
				灯泡
			方法:
				按灯泡
				打开台灯
					灯泡发光
		测试:
			创建灯泡对象
			创建台灯对象
			台灯调用按灯泡的方法,传递灯泡对象(接口对象)
			台灯调用打开台灯的方法
				灯泡对象(接口对象)调用发光的方法
总结:
	步骤:
		1,在A中创建接口对象
		2,在A中使用B对象调用b1方法,将接口对象传入B中
		3,在A中使用B对象调用b2方法,在b2方法中使用接口对象调用方法

Day13:内部类

内部类

出现的原因:补充外部类的功能
内部类:在类中定义的类
外部类:在java文件中,类或接口以外定义的类

内部类分类

1.类中,方法以外
	静态内部类
	成员内部类
2.方法中
	局部内部类
3.实参或值
	匿名内部类
成员内部类
定义:在类中方法以外,在定义一个类
类中有:
	代码块,但是不能有静态代码块
	可以有普通属性,但是不能有静态属性
	可以有构造函数
	可以有普通方法,但是不能有静态方法
	可以有抽象方法
总结:成员内部类不能有静态相关的属性,方法,代码块

如何创建对象:
	外部类类名.内部类类名 对象名 = 外部类对象.new 内部类类名(实参列表);
	注意:
		内部类所在的外部类的方法中创建内部类对象
			普通方法:因为里面有this,所以可以直接创建
			静态方法:因为不能使用this与super,所以需要先创建外部类方法与外部类对象,再创建内部类对象
			
当内部类属性与外部类属性重名时如何区分:
	this.属性名(内部类属性)
	外部类名.this.属性名(外部类属性)
	
当内部类方法与外部类方法重名时如何区分:
	this.方法名(实参列表):内部类方法
	外部类类名.this.方法名(实参列表):外部类方法
静态内部类
定义:在类中方法以外,再定义一个类(给成员内部类中static修饰)
类中有:
	外部类有的,静态内部类都有
	
如何创建对象:
	外部类类名.内部类类名 对象名 = new 外部类类名.内部类类名(实参列表);
	内部类所在的外部类的方法中创建类对象,直接创建
	
当内部类属性与外部类属性重名时如何区分:
	this.属性名:内部类属性
	内部类类名.属性名:内部类静态属性
	外部类类名.属性名:外部类静态属性
	注意:静态内部类中不能使用外部类非静态成员(非静态属性与非静态方法)
局部内部类
定义:方法中定义的类
类中有:
	非静态的属性,方法,代码块,构造函数
	
如何创建对象:
	在该方法中定义该内部类后,直接创建
	内部类类名 对象名 = new 内部类类名(实参列表);
	注意:只能在该方法中创建
	
当内部类属性与外部类属性重名时如何区分:
	this.属性名(内部类属性)
	外部类类名.this.属性名:外部类属性

匿名内部类(**)

概念:没有类名的内部类
	便于书写
缺点:
	1,一个匿名内部类只能创建一个对象
	2,每个匿名内部类都会生成一个class文件
	3,导致代码混乱,不易阅读
总结:
	父类名/接口名 对象名 = new 父类名/接口名(){
		属性
		方法
			重写的方法
			特有的方法
	}

Object(*)

作用:所有类的父类
因为多态所有的类的对象都可以转换为Object对象
因为继承所有所有类都拥有Object提供的属性与方法
方法:
	toString:将对象转换为字符串
		Object提供的该方法是返回对象所属的类的路径@对象的哈希码值(16进制的)
		打印对象时,默认会调用对象的toString方法
		所以重写toString方法,可以让打印对象时,打印的是对象的属性值,以便于观察
	hashCode:获取对象的哈希码值
	equals:
		Object提供的该方法是比较两个对象内存地址是否相同
	getClass:反射时讲
	notify:线程间通讯
	notifyAll:线程间通讯
	wait:线程间通讯
	finalize:当对象所在的堆内存被GC回收时,由JVM调用该方法

System

概念:系统
常用方法:
	作用:拷贝数组
	public static void arraycopy(Object src,  int  srcPos,Object dest, int destPos, int length);
    1,原数组
	2,开始位置(下标的位置)
	3,新数组
	4,新数组的开始位置(下标的位置)
	5,拷贝的数据个数
	
	作用:结束程序
	public static void exit(int status)
	参数为0正常退出,非0,不正常退出
	
	作用:调用java垃圾回收机制(GC)
	public static void gc()
	调用时机:
		1,当内存快满时,由JVM自动调用
		2,使用System.gc()手动调用垃圾回收机制
		
	作用:获取当前时间与1970年1月1日00:00:00的毫秒值(格林威治时间)
	public static native long currentTimeMillis();

Arrays

作用:集合工具

常用方法:
	排序:
		public static void sort(数组)
	将数组转换为特定格式的字符串
		public static String toString(数组)

Day14

包装类

概念:八个基本数据类型对应的类
基本数据类型		对应的引用数据类型
byte				Byte
short 				Short
int					Integer
long				Long
float 				Float
double				Double
boolean				Boolean
char				Character

自动装箱
	概念:将基本数据类型转换为对应的引用数据的对象
	如:
		Integer num = 10;
自动装箱
	概念:将引用数据类型的对象转换为对应的基本数据类型
	如:
		int num02 = num;
		
八个基本数据提供的方法:
	Integer
		public static int parseInt(String s):将字符串转换为整数
		要求:字符串必须是整数数字
		public static int max(int a, int b):获取a,b的最大值
		public static int min(int a, int b):获取a,b的最小值
		public static String toHexString(int i):把10进制的数i,转换为16进制的字符串
	Double
		public static double parseDouble(String s):将字符串转换为小数
		要求:字符串必须是数字
	Boolean
		public static boolean parseBoolean(String s):将字符串转换为boolean
		注意:除true字符串外(忽略大小写比较),全是false
	注意:字符串无法转换为字符

字符串相关

不可变字符串
	String
	特点:会在常量区多次占据内存,大量运算时导致程序卡顿,甚至崩溃
	方法:
		equals:重写Object的方法,可以用来判断字符串内容是否相同
		equalsIgnoreCase:忽略大小写比较
		startsWith:判断字符串以什么开始
		trim:忽略前后空白
		contains:判断子字符串是否在当前字符串中存在
		indexOf:判断子字符串在字符串中第一次出现的位置,如果不存在返回-1
		lastIndexOf:判断子字符串在字符串中最后一次出现的位置,如果不存在返回-1
		length:获取字符串长度
		toCharArray:将字符串转为字符(char)数组
		getBytes:将字符串转化为字节(byte)数组
		new String(byte[] bs):将字节数组转换为字符串
		new String(char[] cs):将字符数组转换为字符串
		new String(bytes, charset):将字节数组转换为特定编码格式的字符串(charset:编码格式)
		charAt(int index):获取字符串指定位置的字符
		replace(oldStr, newStr):替换
		substring(开始位置):截取,从开始位置到字符串末尾
		substring(开始位置,结束位置):截取,从开始到结束位置-1
		split(字符串):切割
			参数:按照什么切割字符串
		toUpperCase:将小写字母转换为大写字母
		toLowerCase:将大写字母转换为小写字母
		
可变字符串
	StringBuffer:
		特点:
			1.线程安全的
			2.在多线程,速度比StringBuilder慢了一些
		常用方法:
		append:给尾部添加
			1.要添加的字符串
		insert:插入
			1.插入的位置
			2.插入的字符串
		delete:删除
			1.开始位置
			2.结束位置
		replace:替换
			1.开始位置
			2.结束位置
			3.替换后的字符串
		toString:转换为字符串
	StringBuilder
		特点:
			1,线程不安全
			2,在多线程,速度比StringBuffer快了一些
		常用方法:
			append:给尾部添加
				1:要添加的字符串
			insert:插入
				1:插入的位置
				2:插入的字符串
			delete:删除
				1:开始位置
				2:结束位置
			replace:替换
				1:开始位置
				2:结束位置
				3:替换后的字符串
			toString:转换为字符串

BigDecimal

作用:计算小数
注意:
	创建时参数用String型的字符串
方法:
	add:加法
	subtract:减法
	multiply:乘法
	divide:除法(得到结果用科学计数法表示)

时间相关(了解)

Date
作用:时间
构造函数:
	new Date():获取当前时间的对象
	new Date(long time):获取距离1970年1月1日 00:00:00的时间(格林威治时间)
	getTime():获取当前时间距离1970年1月1日00:00:00的时间(格林威治时间)的毫秒值
Calendar
作用:日历
创建对象:
	getInstance()
	set
	get
	getTime():将Calendar转换为Date对象
SimpleDateFormat
作用:日期格式化
方法:
	1.将时间转换为特定格式的字符串format
	2.将特定格式的字符串转换为时间parse
注意:
	y:年
	M:月
	d:天
	h:12小时制
	H:24小时制
	m:分钟
	s:秒
	s:毫秒

整数缓冲区(了解)

-128~127
原因:Java源码中预设了这段内容的数对应的对象
导致:
	Integer对象的值在-128~127之间,判断地址是否相同时,结果为true
	超过这个范围,结果为false

Day15:泛型\异常

泛型

作用:将数据类型作为参数进行传递
泛型的定义
语法:
	
	注意:上述字母随便定义
情况:
	1.在方法上定义
		使用:在修饰符之后,返回类型前调用
	2.在类上定义
		使用:
			类名之后
		注意:
			在继承关系中,父类有泛型,子类也必须定义该泛型
	3.在接口上定义
		使用:
			接口名之后
		注意:
			在继承关系中,父接口有泛型,子接口也必须定义该泛型
			在实现关系中,父接口有泛型,子类也必须定义该泛型
	注意:
		静态方法不能定义泛型
		静态常量也不能定义泛型
泛型的应用
使用:
	1.在方法中使用
		在任何一处可以使用数据类型的地方,如返回值类型,形参列表,局部变量的数据类型
	2.在类上定义
		创建该类对象时,必须指明泛型所对应的数据类型
		
注意:泛型中只能接收引用数据类型(***)

异常:Throwable

分类
错误:Error
	原因:因为硬件不足,导致程序崩溃
	处理:不处理
	OutOfMemoryError:内存溢出,可以通过优化解决
异常:Exception
	检查异常
	
	运行异常
		原因:程序员在写代码时,对情况考虑不周全导致的
			需要处理
常见的异常
数组下标越界:ArrayIndexOutOfBoundsException
空指针异常:NullPointerException
算数异常:ArithmeticException
类型转型异常:ClassCastException
...
异常传递
A中调用B,B中调用C...
	在该调用中其中有一个方法有异常,并没有处理,那么就会引起上一个方法出现该异常,最终传递给JVM
	JVM对异常的处理方案是结束产生该异常的程序,用户体验为闪退
异常的处理
解决异常
	语法:
		try{
			有可能产生异常的代码
		}catch(异常类型1 变量名){
			处理方案
		}catch(异常类型1 变量名){
		
		}
		...
		finally{
			不管怎样都执行的代码区
		}
	注意:catch中异常类型先子后父

声明异常
	语法:
		访问权限修饰符 修饰符 返回值类型 方法名(形参列表) throws 异常类型1,异常类型2,...{
		
		}
		
抛出异常
	语法:
		throw(配合throws使用)
自定义异常
1,创建一个类
2,使继承与一个异常
3,提供一个无参构造函数调用父类无参构造函数或者调用父类有参构造函数
	注意:父类构造函数中的实参为错误信息

Day16:集合(1)

作用

1.存储一组数据类型相同的数据
2.集合的长度是根据集合中存储的元素个数决定的,所以长度可变
3.只能存储引用数据类型

体系

Collection(接口)
	List(子接口)
		特点:有序(存入顺序与取出顺序一致),有下标
		ArrayList(子类)
		LinkedList(子类)
	Set(子接口)
		特点:无序(存入顺序与取出顺序不一致),没有下标
		HashSet(子类)
		LinkedHashSet(子类)
		TreeSet(子类)

注意:子类拥有父类的所有属性与方法

Collection

增
	boolean add(E e):添加单个元素
	boolean addAll(Collection c):添加多个元素
	
删
	boolean remove(Object o):删除单个元素
	boolean removeAll(Collection c):删除多个元素
	void clear();清空当前集合中的元素
	
改
	retainAll();两集合交集
	removeAll();两集合差集
	addAll();set集合自动去重,所以直接并集(list集合先做差集,再addAll());

查
	int size();获取集合长度
	boolean isEmpty():判断集合是否为空
	boolean contains(Object o):判断集合中是否存在该元素
	boolean containsAll(Collection c):判断多个元素是否存在
	Iterator iterator();获取迭代器
		boolean hasNext():判断当前位置下是否还存在别的元素
		E next();移动当前位置,到下一个元素的位置,并获取下一个元素
	Object[] toArray():将集合转换为数组
List
增
	boolean addAll(int index, Collection c):给集合指定位置插入多个元素
	void add(int index, E element):指定位置插入一个元素
	
删
	E remove(int index):删除指定位置的元素
	
改
	E set(int index, E element):将指定位置的元素修改为参数
	
查
	E get(int index):查询指定的元素
	int indexOf(Object o):查找指定元素第一次所在位置
	int lastIndexOf(Object o):查找指定元素最后一次所在位置
ArrayList
数据结构:数组(线性表)
优点:查询效率快
缺点:增删速度慢
从内存的角度来看数据结构是在内存中连续开辟一片空间
LinkedList
数据结构:链表
优点:增删速度快
缺点:查询速度慢
从内存角度来看链表结构是离散的在内存中开辟多个空间
分类:   单链表    双链表

Day17:集合(2)

Set

可以重写对象的hashCode()和equals()实现不同对象里面值完全相同时去重
HashSet
数据结构:红黑树+哈希码

特点:
	1.不允许重复
	2.允许null作为值,进行存储
	
存储原理:
	调用本次存储的对象的hashCode方法,获取其哈希码值
	如果该对象的哈希码值与集合中的其他元素的哈希码值不同,直接存储
	如果该对象的哈希码值与集合中其他元素的哈希码值相同,调用该对象的equals方法,让其与集合中所有对象一一比较,如果都不相同,存入集合.如果有一个相同,那么认为集合中已经存在改数据,将其删除	
LinkedHashSet
数据结构:红黑树+链表+哈希码

特点:有序(链表实现)
TreeSet
数据结构:红黑树(要有实现排序的方法)

方案1:存储的数据拥有比较性
	步骤:
		1.让存储的对象所在的类实现Comparable接口
		2.重写该接口的compareTo方法
		注意:
			如果compareTo返回值为0表示相同,则不在存储
			如果返回值为正数,在放在右叉,反之左叉
方案2:指定比较器
	步骤:
		创建TreeSet时传入实现了Comparator接口的对象
Collections:工具类(了解)

Day18:字典(Map)

存储一组数据类型相同的数据
特点:
	1.一次存储一对数据(这一对数据称为一个键值对)
	2.长度可变
	3.key不能重复

名词解释

Map
	HashMap
	Hashtable
	TreeMap
	Properties

Map提供的方法

增
	V put(K key, V value);
	void putAll(Map m);
删
	V remove(Object key);
	void clear();
改
	V put(K key, V value);
		注意:Map中已经存在该key
查
	int size();
	boolean isEmpty();是否有键值对
	boolean containsKey(Object key);是否存在
	boolean containsValue(Object value);
	V get(Object key);
	Set keySet();
	Collection values();所有value的集合
	Set> entrySet();
		K getKey();
		V getValue();

HashMap与Hashtable

不同点:
	HashMap:
		1.允许null作为key或value
		2.jdk1.2
		3.线程不安全的
		4.在多线程情况下效率高
	Hashtable:
		1.不允许null作为key或value(会产生空指针异常)
		2.jdk1.0
		3.线程安全的
		4.在多线程情况下效率低
		
相同点:
	其中的数据排序是依照key的哈希值进行排序的
	数据结构:
		红黑树+哈希值

TreeMap

注意:
	1.要么key拥有比较性Comparable
	2.要么指定key的比较器
数据结构:
	红黑树

Properties

特有方法:
	修改
	public synchronized Object setProperty(String key, String value)
	加载
	public synchronized void load(Reader reader)
	加载
	public synchronized void load(InputStream inStream)
	通过key获取对应的value
	public String getProperty(String key)
	通过key获取对应的value,如果字典中不存在该key,返回defaultValue对应的值
	public String getProperty(String key, String defaultValue)

Day19:线程(1)

进程:一个正在进行的程序
线程:一个执行路径
	主线程:一个进程在启动自带一个线程,该线程被称为主线程(main线程)
	子线程:除主线程外的其他线程,都称为子线程
	多线程:一个进程中有多个线程,就称为多线程

线程的理解

宏观:
	多个线程是同时执行的
微观:
	多个线程是交替执行
	如:
		一个进程中有两个线程
		这两个线程都启动了
		这两个线程会抢夺CPU执行权
		当线程A抢夺CPU执行权后,线程B就陷入了就绪状态
		注意当线程A中抢夺到本次CPU执行权后,可以执行一段时间(一段用纳秒衡量)
		当这段时间完毕后,将释放CPU执行权,让线程A,B在此抢夺

线程的创建方式

方案一:创建Thread的子类对象(了解)
	注意:是将线程与线程任务融合在一起
	方式1:创建Thread的子类,并重写run();
		步骤:
			1.创建类,使其继承与);
		步骤:
			1.创建类,使其继承与Thread
			2.重写run();
			3.创建该类对象
	方式2:使用匿名内部类创建Thread的子类,并重写run()
		Thread thread = new Thread() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				super.run();
			}
		};
	
方案二:创建Thread时传入Runnable的子类对象(建议使用)
	注意:是将线程(Thread)与线程任务(Runnable)分开
	方式1:创建Runnable(接口)的子类对象,在创建Thread对象时传入该对象
	方式2:使用匿名内部类创建Runnable的子类对象,在创建Thread对象时传入该对象

线程常用的方法

启动:
	start();
销毁:
	线程一旦被启动,将不受控制
	当该线程中run()中的代码执行完毕后,等待GC回收
线程的休眠:
	sleep(long time);
	注意:
		1.单位毫秒
		2.当线程休眠后,不会抢夺CPU执行权
		3.使用Thread类调用该方法,是让当前线程休眠
获取当前线程:
	Thread.currentThread();
线程的名称:
	获取线程名称
		String 变量名 = 线程对象.getName();
	设置线程名称
		线程对象.setName(线程名称);
		注意:在线程启动前
			创建线程对象时(直接设置名称)
				new Thread(线程名称);
			new Thread(线程任务,线程名称);
线程的优先级
	线程对象.setPriority(优先级);
	注意:
		1,优先级取值范围1~10
		2,在线程启动前设置
线程的礼让
	Thread.yield();
	注意:
		当该线程获取到CPU执行权后,释放CPU执行权,从新参与抢夺
线程的合并
	线程对象.join();
	注意:
		将调用该方法的线程对象对应的线程,合并到当前线程中
守护线程
	线程对象.setDaemon(true);
	注意:
		一个进程中有任意一个前台线程存活,那么当前线程将不会被GC回收
		如果一个进程中所有的前台线程都执行完毕,那么不管是否有守护线程,都会被GC回收
		默认创建的都是前台线程

线程安全(*)

多个线程同时操作一个数据导致的
线程安全的解决方案
思路:保证同时只能有一个线程在操作该数据
关键字:
	synchronized
使用:
	同步代码块中
		synchronized(锁对象){
			要同步的代码
		}
		注意:在任何对象都可以作为锁对象,但是要保证多个线程使用的是同一个锁对象
		
	同步方法:
		访问权限修饰符 synchronized 返回值类型 方法名(形参列表){
			方法体
		}
		注意:同步方法的锁对象是this.但是要保证多个线程使用的是同一个对象
		
	同步静态方法:
		访问权限修饰符 synchronized static 返回值类型 方法名(形参列表){
			方法体
		}
		注意:同步静态方法的锁对象是类对象,一个类只有一个类对象(JVM生成的对象)

死锁

原因:多个线程互相持有对方所需的锁资源

表现:大量占用CPU,但是程序又没有起到任何效果

解决:尽量不要在同步中使用同步

避免死锁

线程间通讯

注意:
	1.是Object提供的方法
	2.必须是在同步中使用,如同步代码块,同步方法,同步静态方法
	3.必须使用所在同步的锁对象调用

方法:
	notify():随机唤醒一个调用该方法的对象,作为锁对象的线程
	notifyAll():唤醒所有调用该方法的对象,作为锁对象的线程
	wait():
		让当前线程进入无限期休眠
	wait(timeout);
		让当前线程进入有限期休眠
		参数:休眠时间,单位毫秒
	wait(timeout, nanos);
		让当前线程进入有限期休眠
		参数1:休眠时间,单位毫秒 参数2:休眠时间,单位纳秒
		
	wait与sleep的区别:
		1.wait是Object提供的,sleep是线程对象的
		2.wait只能在同步中使用,sleep没有限制
		3.wait可以有限期,也可以无限期,sleep只能有限期
		4.wait在休眠会释放锁对象,sleep不会

线程的状态

创建
就绪
执行
休眠
	有限期
	无限期
销毁

Day20:线程池

生产者与消费者

什么是设计模式:
	针对特定问题,给出的解决方案
场景
	工厂卖货
	对象:
		生产的工人
		销售的工人
		工厂
	类
		工厂类
			数字:记录库存数量
			数字:记录最大库存数量
			生产的方法
				判断库存是否已满
				满了
					当前生产线停止
				没满
					一次生产一个
					唤醒销售线程
			销售的方法
				判断库存是否有货
				有货
					一次销售一个
					唤醒生产线程s
				没货
					当前销售线停止
					
		生产者类(线程任务)
			属性:
				name
				工厂对象
			构造函数:
			set方法
			重写run方法
				死循环调用生产的方法
		消费者类(线程任务)
			属性:
				name
				工厂对象
			构造函数:
			set方法
			重写run方法
				死循环调用销售的方法
				
		环境类
			1,创建工厂对象
			2,创建生产者对象
			3,创建消费者对象
			4,创建线程对象
			5,启动线程

你可能感兴趣的:(java,jvm,开发语言)