一.概述
计算机(Computer)全称:电子计算机,俗称电脑。是一种能够按照程序运行,自动、高速处理数据的现代化智能电子设备。
常见的形式有台式计算机、笔记本计算机。按照规模分为微型机、小型机、大型机、巨型机(超级计算机)等。
计算机发明者约翰•冯•诺依曼。计算机是20世纪最先进的科学技术发明之一,对人类的生产活动和社会活动产生了极其重要的影响,
并以强大的生命力飞速发展。它的应用领域从最初的军事科研应用扩展到社会的各个领域,已形成了规模巨大的计算机产业,
带动了全球范围的技术进步,由此引发了深刻的社会变革,计算机已遍及一般学校、企事业单位,进入寻常百姓家,成为信息社会
中必不可少的工具。
计算机是由硬件系统和软件系统所组成,没有安装任何软件的计算机称为裸机。
计算机硬件系统通常由CPU、主板、内存、电源、主机箱、硬盘、键盘、鼠标,显示器等多个部件组成。
计算机软件按照其功能划分为系统软件与应用软件。Java语言发展史
2.1詹姆斯•高斯林(James Gosling),与Patrick,Naughton和Mike Sheridan等人合作“绿色计划”,后来发展一套语言叫做“Oak”,后改名为Java。
2.2 Java语言平台版本
J2SE/JAVASE — Standard Edition—标准版/基础版
开发普通桌面和商务应用程序提供的解决方案,该技术体系是其他两者的基础。
J2EE/JAVAEE — Enterprise Edition— 企业版/商务版
是为开发企业环境下的应用程序提供的一套解决方案,主要针对于企业级应用程序开发。
J2ME/JAVAME — Micro Edition — 微型版/移动版
是为开发移动设备和嵌入式设备(电器、机器人、机顶盒…)提供的解决方案。Java不是不侧重,而是分支出安卓。
2.3 Java语言特性
简单性 安全性 面向对象 高性能 编译性 解释性 分布式处理 健壮性 开源 跨平台jdk安装
3.1JDK简介
JDK是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。
编写Java程序必须使用 JDK,它提供了编译和运行 Java 程序的环境。是整个java开发的核心。
3.2配置环境变量
右键“我的电脑”→“属性”→“高级系统设置”→“环境变量”按钮,打开环境变量配置对话框
3.3.新建系统变量JAVA_HOME
变量名:JAVA_HOME
变量值:C:\Program Files\Java\jdk1.8.0_291 (默认安装的JDK根目录)
3.4.新建 CLASS_PATH 位置:C:Program FilesJavajdk1.8.0_301\lib;<—jdk的库目录
3.5.修改系统变量Path,Path变量系统本身就有,不需要新建,而且它其中之前的任何值都不要修改
Path的变量值就是JDK的bin目录:
C:\Program Files\Java\jdk1.8.0_291\bin;
或者: %JAVA_HOME%\bin <–jdk的bin目录
Windows10 电脑,新添加一条变量值C:\Program Files\Java\jdk1.8.0_291\bin;
3.6.测试:win+R–>cmd–>java -version–>出现版本信息即可.
输入javac后回车,会输出一些关于javac的帮助信息,帮助我们进行操作使用
输入java之后,回车,输出配置信息如图所示
注:以上三种命令均正常显示,表明JDK环境变量已配置成功
cd 文件所在的路径;
javac -encoding utf8 Test.java
java TestJRE是Java Runtime Environment缩写,只运行,不编写是可以只安装这个,
指Java运行环境,是Sun的产品。运行JAVA程序所必须的环境的集合,包含JVM标准实现及Java核心类库。JVM是Java语言能够跨平台的前提,但是JVM本身不跨平台。JVM(Java Virtual Machine,Java虚拟机)负责运行.class的字节码文件JVM是JRE的一部分。它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。而现在我们安装JDK时也附带安装了JRE(当然也可以单独安装JRE)。粗略分来,JVM的内部体系结构分为三部分,分别是:类装载器(ClassLoader)子系统,运行时数据区,和执行引擎。
二.基础
标识符
定义:标识符可以简单的理解成为一个名字,给对应的元素起的名称就称为标识符,
Java中有很多元素如类名,方法名,字段名,变量名等。
标识符的命名规则:
1.标识符由字母,数字,下划线,美元符号组成,但不包括@、%、"、空格等其它的特殊字符。
2.不能以数字,下划线,美元符号开始开头,也不能以下划线或美元符号结束。
3.严格区分大小写,不应使用拼音与英文混合的方式,更不允许直接使用中文的方式。
4.不能是java的关键字和null,true,false。
5.标识符的命名最好能起到相对应功能的作用,如见名知意。
6.类名用大驼峰,方法用小驼峰命名,常量字母全部大写若有多个用下划线隔开。关键字:
在java中一些单词被赋予了特定的意义,即关键字。
一共有50个关键字,而且都是小写,有两个保留字const和goto。注释:
1.单行注释:每行都以”//”开头.
快捷方式: Ctrl+/ 添加注释,同样的快捷键,再按一次取消注释。
2.多行注释:注释多行内容,虽然叫多行注释,也可注释单行内容.
格式: 以” /* ”开头, 以” * / ”结束.
快捷方式: 可以输入” /* ”之后按回车或Ctrl+shift+/添加注释。
3.文档注释: 一般用来注释类和方法,通过注释内容来记录类或者方法的信息,
还可以添加一些作者/时间/版本…的信息。
格式: 以” /** ”开头。 以” * / ”结尾
快捷方式: 输入 “ /** ” 之后按回车添加注释。变量:
1.定义:在java当中一些数据的值不是固定不变的,总在变化的数据称为变量。
2.变量的三个元素:变量类型 变量名 变量值。
3.定义变量的两种格式:
格式一:声明变量的同时进行赋值:int age = 18;
格式二:先声明变量:String name ; 然后给变量赋值:name = “Reimu”;
4.变量名必须是一个有效的标识符,变量名不可以使用java关键字,null,true,fulse;变量名不能重复。
变量的使用原则:就近原则,即尽量控制变量的使用范围到最小。
变量分类:(成员变量,局部变量)
成员变量: 1.位置:定义在类里方法外; 2. 注意事项:不用初始化,也会自动被初始化成默认值;
5.作用域:整个类中,类消失了,变量才会释放。
局部变量 1.位置:在方法或者局部代码块当中; 2.注意事项:必须手动初始化即给变量赋值;
6.作用域:在方法或局部代码块中,当对应代码块执行完毕,局部变量也随之释放常量
定义:在程序运行过程中,值一直不会改变的量成为常量。数据类型(基本类型和引用类型):
Java是一个强类型的语言,变量保存在内存当中时,就需要向内存申请存储空间。
为了方便内存管理系统,根据变量类型更加合理的分配内存空间会把常见的数据
分成不同类型,不同类型分配的内存大小是不同的,这个大小的单位就是字节Byte。
二进制位bit,来自英文bit,音译为“比特”。
1 Byte = 8 Bits (1字节 = 8位)
1 KB = 1024 Bytes
1 MB = 1024 KB
1 GB = 1024 MB
6.1.基本类型:
类型 | 名称 | 字节空间 | 取值范围 | 默认值 | 对应的引用类型 |
---|---|---|---|---|---|
整数型 | byte | 1 | -27~27-1或者-128- -127 | 0 | Byte |
short | 2 | -2的15次~2的15次-1 | 0 | Short | |
int | 4 | -2的31次~2的31次-1 | 0 | Integer | |
long | 8 | -2的63次~2的63次-1 | 0L | Long | |
浮点型 | float | 4 | 单精度,对小数部分的精度要求不高 | 0.0f | Float |
double | 8 | 双精度,精确到小数部分,操作值很大 | 0.0d | Double | |
字符型 | char | 2 | 0~65535 | ‘\u0000’ | Character |
布尔型 | boolean | 1 | 真true 假false | FALSE | Boolean |
6.1.1. 基本类型的字面值规则:
整数类型的字面值类型是int类型,只要写一个整数,就被认为是int类型;
浮点数类型的字面值类型是double类型,只要写一个小数,就被认为是double类型;
byte,short,char三种比int小的整数可以用范围内的值直接赋值;
字面值后缀:L(long类型), D(double类型), F(float类型);
进制前缀:0b - 标识2进制 ,0 - 标识8进制,0x - 标识16进制;
char类型可以存数字,但是会从ASCII码表 查出这个数字对应的字符来打印,
想互相通信而不造成混乱,那么大家就必须使用相同的编码规则,
ASCII(American Standard Code for Information Interchange)编码表是美国标准信息交换代码,
中国 gb2312【字少】,gbk【识别4万+汉字】万国码表unicode【ISO制定】,所有码表都兼容ASCII。
6.1.2.基本类型的类型转换:
大小所对应的是数据类型的取值范围,不是当前字节数的大小。
小到大隐式转,大到小强制转,浮变整小数丢。
byte,short,char→ int→ long→float→double
小到大(隐式转换)
int n = m;//小转大,右面的m是小类型,给左面的n大类型赋值,可以直接使用.
float f = 3.14f; double d = f; -->可以执行
大到小(显式转换)
容量大的类型转换为容量小的类型时必须使用强制类型转换
int x = 1000; byte y =(byte)x;//大转小,右面x给左面的y小类型赋值,需要强制类型转换。
在java里a=a+1; 与a+=1的区别:当数据类型不一致时+=隐含了强制类型的转换。
byte a=2; a=a+1; 报错,因为byte类型的变量在参与运算时会自动提升为int类型,
a+1运算完成后会变为int,int赋值给byte时报错;
byte a=2; a+=1;编译通过,输出3,在编译时隐含了强制类型转换,相当于a=(byte)(a+1);
byte b=127; b+=1;输出的结果是-128,所以+=不会进行溢出检查。
转换过程中可能导致溢出或损失精度
例如:int i =128; byte b = (byte)i; //打印的结果是-128
因为 byte 类型是 8 位,最大值为127,所以当 int 强制转换为 byte 类型时,
值 128 时候就会导致溢出。
浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入
例如:float f = 32.9f; int a2 =(int) f; //打印的结果是32。
不能对boolean类型进行类型转换。
6.1.3运算规则:
1.计算结果的数据类型,与最大数据类型一致、
2.byte,short,char三种比int小的整数,运算时会先自动转换成int
3.整数运算溢出,到最大值时,会回到最小进行运算
4.浮点数运算不精确
BigDecimal:常用来解决精确的浮点数运算不精确的问题.
方式一 :BigDecimal(double val)
将double转换为BigDecimal,是double的二进制浮点值十进制表示形式。
方式二 :BigDecimal(String val)
将String类型字符串的形式转换为BigDecimal。
常用方法
Add(BigDecimal bd) : 做加法运算
Subtract(BigDecimal bd) : 做减法运算
Multiply(BigDecimal bd) : 做乘法运算
Divide(BigDecimal bd) : 做除法运算,除不尽时会抛异常
Divide(BigDecimal bd,保留位数,舍入方式) : 除不尽时使用
setScale(保留位数,舍入方式) : 同上
pow(int n) : 求数据的几次幂
舍入方式解析
ROUND_HALF_UP 四舍五入,五入 如:4.4结果是4; 4.5结果是5
ROUND_HALF_DOWN 五舍六入,五不入 如:4.5结果是4; 4.6结果是5
ROUND_HALF_EVEN 公平舍入(银行常用)
比如:在5和6之间,靠近5就舍弃成5,靠近6就进位成6,如果是5.5,就找偶数,变成6
ROUND_UP 直接进位,不算0.1还是0.9,都进位
ROUND_DOWN 直接舍弃,不算0.1还是0.9,都舍弃
ROUND_CEILING(天花板) 向上取整,取实际值的大值
朝正无穷方向round 如果为正数,行为和round_up一样,如果为负数,行为和round_down一样
ROUND_FLOOR(地板) 向下取整,取实际值的小值
朝负无穷方向round 如果为正数,行为和round_down一样,如果为负数,行为和round_up一样
5.浮点数的特殊值:Infinity, 无穷大,NaN 。
//1.查看基本类型的最大值与最小值
//Java给8大基本类型都提供了类型对应的“工具箱”,int类型的工具箱比较特殊,叫做:Integer。
/*1.整形类型:byte short int long*/
byte byteMin = Byte.MIN_VALUE;
byte byteMax = Byte.MAX_VALUE;
short shortMin = Short.MIN_VALUE;
short shortMax = Short.MAX_VALUE;
int intMin = Integer.MIN_VALUE;
int intMax = Integer.MAX_VALUE;
long longMin = Long.MIN_VALUE;
long longMax = Long.MAX_VALUE;
/*2.浮点类型 :float double*/
float floatMin = Float.MIN_VALUE;
float floatMax = Float.MAX_VALUE;
double doubleMin = Double.MIN_VALUE;
double doubleMax = Double.MAX_VALUE;
/*3.boolean布尔类型只有两个值true与false*/
boolean b1 = true;
boolean b2 = false;
/*4.boolean布尔类型只有两个值true与false*/
boolean b1 = true;
boolean b2 = false;
/*5. 字符型的数据需要使用单引号''来包裹,char类型可以存数字,但是会从ASCII码表
查出这个数字对应的字符来打印,128~65535这些数字,也可以保存,但一般显示为?*/
char c1 = 'a';//a,字符型可以保存一个字母
char c4 = 97;//a,字符型可以保存数字,但是会查ASCII,打印的是字符a
//2.变量交换
int a,b;//交换 a b 这两个变量保存的值
int t;//定义一个变量用来辅助值交换
t = a;//把a的值交给t来保存
a = b;//把b的值交给a来保存
b = t;//把t的值交给b来保存
6.2.引用类型:
除了基本类型以外的所有类型都是引用类型。
引用类型是一个对象类型,值指向内存空间的引用,就是地址,
所指向的内存中保存着变量所表示的一个值或一组值。
1.字符串类型(String):用来保存多个字符,需要用双引号包裹。
类,接口,数组等。
- 运算符
定义:运算符 用于连接 表达式 的 操作数,并对操作数执行运算。
分类:算术运算符、比较运算符,赋值运算符、关系运算符、逻辑运算符、位运算符。
运算符按照优先级别的高低排序分别是:自加/减运算符、 算术运算符、比较运算符、逻辑运算符、赋值运算符。
顺序 | 运算符 |
---|---|
1 | 括号,如 ( ) 和 [ ] |
2 | 一元运算符,如 -、++、- -和 ! |
3 | 算术运算符,如 *、/、%、+ 和 - |
4 | 关系运算符,如 >、>=、<、<=、== 和 != |
5 | 逻辑运算符,如 &、^、\、&&、\ |
6 | 条件运算符和赋值运算符,如 ? :、=、*=、/=、+= 和 -= |
7.1.算数运算符:+,-,*,/,%,--,++
%是取余符号,余数是运算结果,整除余数为0
自增运算符:++,给变量本身的值+1
//自减运算符:--,给变量本身的值-1
//前缀式:++a,--a;先改变变量本身的值,后使用
//后缀式:a++,a--;先使用变量,后改变变量本身的值
//普通四则运算不会改变变量本身的值,只会改变算式的结果
7.2.比较运算符: >,<,>=,<=,==,!=,===,!==
7.3.逻辑运算符:&,&&,|,||,+,!
&&:双与短路与:全真为真,遇假则假,全假则假,
1 && 2 ,当1是false时,2会被短路,提高程序的效率。
||:或:有真为真,全假才假,
1 | 2,结果想要是true,要求1和2只要有一个为true就可以
||双或(短路或):1 || 2,当1是true时,2会被短路,提高程序效率。
!:非:真变假,假变真
&单与: 1 & 2 ,结果想要是true,要求1和2都必须是true
7.4.三目运算符:a?b:c;
表达式?为真取这:为假取这;
7.5.赋值运算符 :=,+=,-=,*=,/=
分支结构
8.1单分支结构 判断语句:把比较难满足的条件写到上面 先判断难达到的, 难满足的,在判断普遍的可以减少一定的代码量 if(判断条件){ 执行代码; } 8.2.多分支结构 if(判断条件1){ 满足条件1执行 }else{ 不满足条件1执行 } 8.3.嵌套分支结构 if(条件1){ 代码1; }else if(条件2){ 代码2; }else if(条件3){ 代码3; }else{ 代码4; } 8.4:switch结构 (1.变量a支持类型:byte,short ,char,int ,String,Integer 2.执行顺序:用a的值依次与case后的值进行比较 若匹配,执行case后的值,没有break时会一直向后执行所有case,包括default, 称为穿透现象,若不匹配,就不执行。若设置了default,没有匹配到任何case, 就执行default语句。 3.语句中的break和default是可选项,可根据具体的业务来添加。) switch(a){ case a1: b; break; case a2:c; break; default:d; } break:结束或中断程序 continue:不能在循环之外使用,提高程序的效率,遇到continue可以结束循环进行新的一轮循环 break和continue的后面不能直接写代码,因为后面的是不可到达的代码
循环结构
重复干某件事的时候可以使用循环结构 循环能执行几次,取决于循环变量一共可以取到几个具体的值 一:for循环:知道循环次数 3.1:外层循环执行一次,内层循环全部执行或执行多次 3.2:外层循环控制循环的行数,内层循环控制循环的列数 二:while循环:当循环此数不确定时 先判断,不符合规则就不执行代码 //死循环: whlie(true){} 死循环必须设置程序的出口 三:do-while循环:至少循环一次,循环次数不确定 先执行一次,再去判断,符合规则再次执行代码 do{ 循环体; }while(循环条件);
变量
1.定义: 可以改变的数,称为变量。在Java语言中,所有的变量在使用前必须声明。 一般通过“变量类型 变量名 = 变量值 ;”这三部分来描述一个变量。如:int a = 9 ; 变量的使用原则:就近原则,即尽量控制变量的使用范围到最小。 1.2 局部变量 位置:定义在方法里或者方法的声明上 注意:必须手动初始化来分配内存.如:int i = 5;或者int i; i = 5; 生命周期:随着方法的调用而存在,方法运行完毕就释放了; 作用域:在方法/局部代码块中,对应的代码执行完局部变量就被释放 1.3 成员变量 位置:定义在类里方法外 注意:不用初始化,也会自动被初始化成默认值 生命周期:整个类中,类消失了,成员变量才会释放 作用域:在整个类中生效,类消失,变量才会消失 属性:即特征,类的成员变量来描述,定义在类里方法外的变量。 静态变量和实例变量的区别 在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。 在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象, 其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某 个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码, 不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。 实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接 使用类名来引用。
修饰符权限
default是表示不写修饰符,默认,如果写default单词来修饰会报错
修饰符 | 同类 | 同包 | 字类 | 不同包(无关类) |
---|---|---|---|---|
public | yes | yes | yes | yes |
protected | yes | yes | yes | no |
默认 | yes | yes | no | no |
private | yes | no | no | no |
方法
定义:被命名的代码块,方法可以含参数可以不含参数,可以提高代码的复用性。 完整的方法的定义: 1.定义: 方法的修饰符 方法的返回值 方法名(参数列表){方法体} 或:修饰符 返回值类型 方法名( 参数列表 ){ 方法体 } 2.调用方法:通过方法名+参数列表的方式来确定具体调用哪个方法的功能 方法的返回值需要打印输出 用return返回值接受的类型要一致 方法调用顺序:顺序执行代码,调用指定方法,执行完毕,返回调用位置。 形参:定义出来用来接收数据的 实参:具体的数据,直接使用的 构造方法:创建方法进行初始化 方法的重载 方法的重载是指在一个类中定义多个同名的方法,但是每个方法的参数列表不同(也就是指参数的个数 和类型不同), 程序在调用方法时,可以通过传递给他们的不同个数和类型的参数来决定具体调用哪个方法. 重载:@Overload 重载的条件: 1.在同一个类中 2.多个方法的方法名相同 3.同名方法的参数列表不同 *若参数个数不同,一定构成重载 *若参数个数相同,需查看对应位置上的的参数类型,与参数值无关 用于测试方法的重载现象 * 在同一个类中,存在多个方法名相同,参数列表内容不同的方法 * 如果在同一个类中,同名方法的参数个数不同,一定构成重载 * 如果在同一个类中,同名方法的参数个数相同, * 需要查看参数位置上对应的参数类型,不一定构成重载。如下: * (int a,String b)与(int b,String a)--不构成重载 * (int a,String b)与(String a,int b)--构成重载 意义:为了外界调用方法不方便时,不管传入怎样的参数都可以匹配到对应的同名方法 方法的重写@Override 条件:有继承关系 /*重写:子类对父类的方法不满意时,可以重写父类的方法 意义:在不修改源码的情况下,进行功能的修改与拓展 @Override:注解,只能用来加在重写的方法当中,表示该方法是一个重写方法 格式:修饰符 返回值类型 方法名(参数列表) {方法体} 重写原则:两同 两小 一大 两同:子类方法的 方法名与参数列表 和父类方法的相同; 两小:子类方法抛出的异常类型<=父类方法抛出的异常类型; 子类方法的返回值类型<=父类方法的返回值类型, 即子类方法的返回值类型是父类方法返回值类型的子类的一种继承; 当父类方法的返回值是void时,子类方法的返回值也是void。 * //父:int 子:int 可以 * //父:int 子:long 不可以 * //父:Animal 子:Animal/Cat/Dog... 可以 返回值类型:基本类型是一种,另一种是应用类型 一大:子类方法的修饰符的权限>=父类方法的修饰符的权限
数组
定义:用于存储多个相同类型数据的集合,数组的空间是连续的。 1.数组Array,标志是[ ] ,通过数组的下标来操作数组当中的每一个元素 数组的下标从0开始,最大下标为数组长度减一 2.数组的打印: char类型的数组在底层中做了处理,可以直接打印数组中的元素 除了char类型以外的数组,要查看和使用数组中的具体元素,需要使用 Arrays.toString(数组名);Arrays需要导包 3.数组一旦创建,长度不可改变,数组的长度允许为0。 如果要增加或删除数组的元素,只能先创建一个新的长度的新数组,再将原来的数据复制进去, 数组名是个引用类型的变量,它保存着的是数组的地址,不是数组中的数据。 4.数组的复制 缩容 扩容 //数组的普通复制 copyOf(参数1,参数2);用于数组的复制,有两个参数 参数1:要复制的数组名 参数2:新数组的长度 普通复制:新数组的长度=原数组的长度 //数组的扩容: 扩容:扩充的数组的长度>大于原数组的长度 改变参数2的长度 方法:先创建对应新长度的数组,每个位置上都有默认值 然后从原数组中将对应的元素复制到新数组,未覆盖的位置为默认值 //数组的缩容: 缩容:缩容的数组的容量<小于原数组的长度 改变参数2的长度 方法:先创建对应新长度的数组,每个位置上都有默认值 然后从原数组中将指定个数的元素复制到新数组,类似于截取 */ 一维数组: 静态初始化: int[] a={1,2,3,4,5}; int[] a1=new int[]{1,2,3,4,5}; 动态初始化 int[] a2=new int[5];
创建数组过程分析
程序创建数组int[] a={1,2,3,4,5}; 的过程:
在内存中开辟连续的空间,用来存放数据,长度是5
给数组完成初始化过程,给每个元素赋予默认值,int类型默认值是0
数组完成初始化会分配一个唯一的地址值
把唯一的地址值交给引用类型的变量a去保存
二维数组:
int[][] a = {undefined{3,5},{7,9},{1,2}};
–创建外部数组,长度是3
–给每个外部数组的位置创建内部数组,每个内部数组的长度是2
–给每个内部数组进行数据初始化
–二维数组生成唯一的地址值
–把地址值交给引用类型变量a来保存。
基本类型的数组当中只能存放相对应的基本类型的数据。
数据结构:数组,栈,队列,树
三.面向对象OOP
1.定义:
面向对象:只看结果,变成指挥者
面向过程:强调过程,凡事亲力亲为
2 面向对象的三大特征
封装: 把相关的数据封装成一个“类”组件
继承: 是子类自动共享父类属性和方法,这是类之间的一种关系
多态: 增强软件的灵活性和复用性
3 类和对象
3.1 类
类:可以理解为一类事物的模板,是抽象的,类似于类型(界门纲目科属种),设计图纸,
Java语言最基本单位就是类,相当于类型,类是一类事物抽取共同属性与功能形成的,
注意:类在现实世界并不存在,它只是一种对象的数据类型。
如果一个类没有明确指定它的父类,那它默认继承顶级父类Object
在一个Java文件中可以写多个Class,但被public修饰的class只有一个,
且这个公共类的名字必须与当前文件的名字一致
普通类(外部类):只能用public、default(不写)、abstract、final修饰。
内部类(成员):可理解为外部类的成员,所以修饰类成员的public、
protected、default、private、static等关键字都能使用。
局部内部类:出现在方法里的类,不能用上述关键词来修饰。
匿名内部类:给的是直接实现,类名都没有,没有修饰符。
3.2 对象
对象:是根据类创建出的具体事物,是具体的,通过new关键字创建。
每个对象具有三个特点:对象的属性,对象的功能和对象的标识。
对象的属性用来描述对象的基本特征。
对象的功能用来描述对象的可以完成的操作。
对象的标识是指每个对象在内存中都有一个唯一的地址值用于与其他对象进行区分,类似于我们的身份证号。
3.3 类和对象的关系
我们先创建类,再通过类创建出对象
我们可以通过一个类创建出多个对象
类是抽象的,对象是具体的
Java把内存分成5大区域
一般来讲局部变量存在栈中,方法执行完毕内存就被释放
对象(new出来的东西)存在堆中,对象不再被使用时,内存才会被释放
每个堆内存的元素都有地址值
对象中的属性都是成员变量,是有默认值的
TIPS: 栈与队列指的是一种数据的结构。
栈:先进后出(FILO – First In Last Out)
队列:先进先出(FIFO – First In First Out)
对象创建过程的分析
Phone p;创建地址值,在栈内存开辟
new Phone();创建匿名对象,在堆内存开辟一块空间存放Phone类型的对象
Phone p=new Phone();
内存过程:
1.把Person.class文件加载进内存
2.在栈内存中,开辟空间,存放引用变量p
3.在堆内存中,开辟空间,存放Person对象
4.对成员变量进行默认的初始化
5.对成员变量进行显示初始化
6.执行构造方法(如果有构造代码块,就先执行构造代码块再执行构造方法)
7.堆内存完成
8.把堆内存的地址值赋值给变量p ,p就是一个引用变量,引用了Person对象的地址值
匿名对象
没有名字的对象,是对象的简化表示形式。
使用场景:
当被调用的对象只调用一次时(多次会创建多个对象浪费内存)
也可以写成:
new Demo().show();//创建了一个对象调方法
4.构造函数(构造方法):
概念
构造方法是一种特殊的方法,它是一个与类同名且没有返回值类型的方法
构造方法的主要功能就是完成对象创建或者初始化
当类创建对象(实例化)时,就会自动调用构造方法
构造方法与普通方法一样也可以重载.
格式:与本类类名同名,并且没有返回值类型,可以含参也可以不含参
作用:创建对象,创建一次,执行一次构造函数即构造函数是被动触发的
只有new 对象();时才调用函数。
分类:
无参构造:默认存在,如果添加了其他构造,默认的构造函数会被覆盖
含参构造:对于参数没有要求,有参数就行
全参构造:全参构造的参数必须与本类属性一致,能够创建对象和给对象的所有属性赋值
右键--Generate--Constructor-全选
5.构造代码块{}
1.位置:类里方法外
2.执行:每次创建对象时都会执行构造代码块,构造代码块优先于构造方法执行
3.作用:用于提取所有构造方法相同的功能
局部代码块:{}
1.位置:方法里
2.执行时机:调用该局部代码块所处的方法时才会执行,
优先于所处的方法先执行
3.作用:用于控制变量的作用范围,限制变量的使用范围,当变量的
作用范围越小时,使用越精确
执行顺序:构造代码块-构造方法-普通方法-局部代码块
1.当创建对象时,会触发构造函数;
2.创建对象时,也会触发构造代码块,并且构造代码块优先于构造方法执行
3.创建对象后才能通过对象调用普通方法
4.若普通方法里有局部代码块,才会触发对应的局部代码块
6.关键字:
1.this关键字:
1.当成员变量与局部变量同名时,可以用this关键字指定本类的成员变量;
2.若不使用this指定,打印的就是近处的局部变量,就近原则;
3.在含参构造中,调用无参构造的功能或在无参构造中,
调用含参构造的功能,只能单项调用,否则会陷入死循环;
规定:this关键字必须在构造函数或方法的第一行,才可以调用构造方法的功能
this();---调用的是本类的无参构造
this(参数);---调用的是本类对应参数额构造方法
2.super关键字:
位置:函数或方法里
1.当父类的成员变量与子类的成员变量或属性同名时,使用super来指定父类的成员变量
2.使用super关键字必须在构造函数或方法的第一行,才可以调用构造方法的功能
super();---调用的是本类的无参构造
super(参数);---调用的是本类对应参数额构造方法
3.static关键字:
1.被static修饰的资源统称为静态资源;
2.静态方法可以直接调用,静态资源资源可以直接通过类名调用,即使没有创建对象也可以调用;
3.静态资源是随着类加载而加载到内存中的,比对象先进入内存,
4.位置:在成员变量或方法当中修饰,不能放在局部变量当中
5.静态资源在内存中只有一份,被全局所有对象共享,当我们通过任意一种方式修改了静态变量的值后,
不管用何种方式查看,静态变量的值都是刚刚修改后的值;
6.调用:静态资源只能调用静态的资源,普通资源可以调用静态的资源 。
/*创建本类的静态代码块
格式:static{}
位置:类里方法外
执行时间:静态代码块也属于静态资源,随着类的加载而加载,优先于对象先加载,并且静态资源只会加载一次;
作用:用于加载那些需要第一时间就加载,并且只加载一次的资源,常用来初始化
*/
执行顺序:静态代码块--构造代码块--构造方法---普通方法--局部代码块
静态方法不存在重写的概念,不可以与this和super共用,若有多个静态资源,加载顺序取决于位置的先后顺序
4.final关键字:最终类
1.final可以用来修饰类,被final修饰的类是最终类,不可以被继承,
可以把被final修饰的类看为树结构的叶子节点.
2.final可以用来修饰方法,被final修饰的方法是该方法的最终实现,不可以被重写.
3.被final修饰的是常量,常量的值不可被修改,不论是成员位置还是局部位置,常量定义时必须赋值,
并且常量的名称定义时必须是全大写,单词与单词之间用下划线分隔开。
7.封装:隐藏对象的真实属性和实现细节,只对外提供公共的访问方式,如类和方法
封装属性思路:
1.用private修饰资源
2.提供公共的get方法--用来获取值
3.提供公共的set方法--用来设置值
封装方法的思路:
1.用private修饰资源
2.用本类的公共方法调用这个被封装方法的功能
好处:提高安全性,提高重用性。
private关键字
是一个权限修饰符 ,可以用来修饰成员变量和成员方法.被私有化的成员只能在本类中访问。
我们可以使用private关键字来封装成员变量与方法
如何访问私有资源:
关于成员变量:
setXxx – 对外提供公共的设置值方式
getXxx – 对外提供公共的获取值方式
关于成员方法:
把私有方法放在公共方法里供外界调用即可
8.继承:
定义:继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并扩展出新的能力。
Java的继承是从已存在的类的定义作为基础创建新类的技术
新类的定义可以增加新的数据和新的功能,也可以使用父类的功能,但不能选择性继承父类
优点:可以轻易的复用以前的代码,能够大大的缩短开发的周期,降低开发费用
特点:
1.通过extends关键字来建立子类与父类的继承关系
格式:子类 extends 父类;
2.Java只支持单继承,一个子类只能有一个父类,但是一个父类可以有多个子类
3.继承具有传递性,爷爷类的功能会传给爸爸,爸爸的功能能传给孙子,相当于子类将父类的功能复制了一份
4.子类继承了父类以后,可以使用父类所有的非私有的资源,私有资源被private限制,没有访问权限
5.继承是 is a 的关系,如小猫是小动物,看到子类或父类中的一个可以推测出另一个
6.继承要求子类必须是父类的一种下属的类型,依赖性非常强,是强耦合
7.当父类的成员变量与子类的成员变量相同时,可以使用super指定父类的成员变量,
把super当作父类的对象:Father super=new Father();
当子类成员变量或局部变量与父类的成员变量不同时,可以直接使用父类的成员变量
向上转型和向下转型:
子类可以复用父类的功能,如果父类不能满足当前子类的需求,则子类可以重写父类中的方法来加以扩展。
那么在这个过程中就存在着多态的应用。存在着两种转型方式,分别是:向上转型和向下转型。
向上转型:可以把不同的子类对象都当作父类来看,进而屏蔽不同子类对象之间的差异,写出通用的代码,
做出通用的编程,统一调用标准。向上转型时,子类对象当成父类对象,只能调用父类的功能,如果子类
重写了父类中声明过的方法,方法体执行的就是子类重过后的功能。但是此时对象是把自己看做是父类类型的,
所以其他资源使用的还是父类型的。
向下转型(较少):子类的引用的指向子类对象,过程中必须要采取到强制转型。这个是之前向上造型过的子类
对象仍然想执行子类的特有功能,所以需要重新恢复成子类对象
Parent p = new Child();//向上转型,此时,p是Parent类型
Child c = (Child)p;//此时,把Parent类型的p转成小类型Child
9多态:
前提:类的继承,方法的重写
父类引用指向子类的对象:Animal a=new Cat();
在多态当中,编译看左边,运行看右边
java源代码.java---(编译保存)-->java字节码.calss字节码文件---(运行执行)-->JVM运行.class得到结果
1.多态的前提:继承+重写;
2.父类对象不能使用子类的特有功能。
3.父类的引用类型指向子类的对象,创建出来的子类对象的地址值,交给父类类型的引用类型变量来保存。
4.编译(保存)看左边,运行(效果)看右边:必须要在父类中定义该方法,才能通过编译,把多态对象看作是父类类型;
必须要在子类中重写该方法,才能满足多态,实际干活的是子类。
编译看左边:必须父类定义了方法,才能通过编译
运行看右边:必须要在子类中重写该方法,才能满足多态,实际干活的是子类
//多态当中成员变量使用的是父类的
System.out.println(a.sum);//10
//多态中方法的声明使用的父类的,方法体使用的是子类的
a.eat();
多态的调用:不论是父类对象还是子类对象,都可以调用getFruit()方法
//利用多态,将子类类型的对象看作父类类型
使用:
多态对象把自己看做是父类类型
成员变量: 使用的是父类的
成员方法: 由于存在重写现象,所以使用的是子类的
静态成员: 随着类的加载而加载,谁调用就返回谁的
10.异常:
定义:异常是一些用来封装错误信息的对象,
由异常的类型、提示信息、报错的行号提示三部分组成。
输入32和0报错:ArithmeticException---算术异常,除数不能为0---by zero
*输入11和54.3报错:InputMismatchException---输入不匹配异常
* 1.不要害怕BUG,不可能全知全能
* 2.学会看报错的信息,确定自己错误的方法
* 3.学会看报错的行号提示,确定自己报错的位置,哪里不对点哪里
* 源码一般不会有错,主要看自己的代码
异常处理的方式1:
//使用多态的思想,不论什么子异常,统一看为父类型Exception,
做出通用的解决方案 //try-catch结构可以嵌套,如果有多种异常类型需要特殊处理,可以进行嵌套。
try{
可能会抛出异常的代码块;
}catch(异常类型1 异常名){
如果捕获到了异常,进行处理的解决方案;
}catch(异常类型2 异常名){
如果捕获到了异常,进行处理的解决方案;
}catch (Exception e){
System.out.println("ERROR!!");
}
异常处理的方式2:
Unhandled exception: 未处理的异常。
加入一个新方法解决,main()不直接调用会抛出异常的method()3方法,
而是调用新加入的方法解决抛出的异常。
定义一个异常的解决方法:
异常抛出的格式:在方法的小括号与大括号之间,写:throws 异常的类型
若有多个异常,使用逗号分隔即可。
如果一个方法抛出了异常,那谁来调用这个方法,就需要谁来解决该异常,
处理方法有两种:捕获解决或继续向上抛出
注意:一般会在main()方法调用之前解决异常,不是将问题抛给main(),
main()是JVM,这样没人解决问题还是报错。
throws 与 throw 的区别
throws
用在方法声明处,其后跟着的是异常类的名字
表示此方法会抛出异常,需要由本方法的调用者来处理这些异常
但是注意:这只是一种可能性,异常不一定会发生
throw
用在方法的内部,其后跟着的是异常对象的名字
表示此处抛出异常,由方法体内的语句处理
注意:执行throw一定抛出了某种异常
四.抽象类
定义:Java中可以定义被abstract关键字修饰的方法,这种方法只有声明,没有方法体,叫做抽象方法.
Java中可以定义被abstract关键字修饰的类,被abstract关键字修饰的类叫做抽象类。
特点
abstract 可以修饰方法或者类
被abstarct修饰的类叫做抽象类,被abstract修饰的方法叫做抽象方法
抽象类中可以没有抽象方法
如果类中有抽象方法,那么该类必须定义为一个抽象类
子类继承了抽象类以后,要么还是一个抽象类,要么就把父类的所有抽象方法都重写
多用于多态中
抽象类不可以被实例化
意义:父类定义可能实现的功能,之后要使用的话可以由子类来实现。
1.被abstract关键字修饰的方法是抽象方法,抽象方法没有方法体。
2.如果一个类中包含了抽象方法,那该类也必须被申明成为一个抽象的类。
3.当一个子类继承了抽象父类之后有两种解决方法:
方法1:变成抽象子类,将子类也变为抽象类
方法2:变成普通子类,实现父类中所有为实现的抽象类的方法,父债子偿.
4.抽象类不可以对象实例化,即不能创建对象,可以创建多态
//抽象类当中可以申明普通属性。
//如果抽象类中都是普通方法,为什么要把该类申明为抽象类呢?
//因为抽象类不可以被实例化,如果不想让外界创建本类的对象,可以把普通类申明成抽象类。
//抽象类当中是否全是抽象方法? 可以有普通方法。
//如果一个类当中有抽象属性或抽象方法,该类就必须被申明成抽象类。
抽象方法要求子类继承后必须重写。
不能与abstract关键字一起使用的有:
1.private:被私有化后,子类无法重写,与abstract相违背。
2.static:静态优先于对象存在,存在加载顺序问题。
3.final:被final修饰后,无法重写,与abstract相违背。
五.接口API
1.定义:接口( Interface )在Java中也是一种抽象类型,接口中的内容是抽象形成的需要实现的功能,
接口更像是一种规则和一套标准。API(Application Programming Interface,应用程序接口)是一些
预先定义的函数。目的是提供应用程序与开发人员基于某软件可以访问的一些功能集,但又无需访问
源码或理解内部工作机制的细节.API是一种通用功能集,有时公司会将API作为其公共开放系统,也就是
公司制定自己的系统接口标准,当需要进行系统整合,自定义和程序应用等操作时,公司所有成员都可以
通过该接口标准调用源代码.
Java.util包是java中的工具包,包含各种实用工具类/集合类/日期时间工具等各种常用工具包
如:import java.util.Scanner; import java.util.Arrays;
java.lang包是java的核心,包含了java基础类,包括基本Object类/Class类/String类/基本数学
类等最基本的类,这个包无需导入,默认会自动导入。
import java.lang.Object;
import java.lang.String;
import java.lang.StringBuilder/StringBuffer;
2.特点:
1.通过interface关键字来定义接口
2.通过implements让子类来实现接口
3.接口中的方法全部都是抽象方法(JAVA8)
4.可以把接口理解成一个特殊的抽象类(但接口不是类!!!)
5.类描述的是一类事物的属性和方法,接口则是包含实现类要实现的方法
6.接口突破了java单继承的局限性
7.接口和类之间可以多实现,接口与接口之间可以多继承
8.接口是对外暴露的规则,是一套开发规范
9.接口提高了程序的功能拓展,降低了耦合性
10.接口里是没有构造方法,如果一个类没有明确指定它的父类,
那么它默认继承顶级父类Object,调用的super()是Object的无参构造
.11.接口当中的成员变量是静态常量,实际写法:public static final int age=20;
12.接口中可以省略修饰符,默认拼接,写成 int age=20; 也可以,
所以,接口当中没有成员变量。
. 13.接口当中抽象方法的定义可以简写,实际写法:public abstract void eat();
会自动给抽象方法拼接public abstract 。
14.接口不是类,可以看为一个特殊的类
15.接口是用来制定规则的
1.我们通过interface关键字来定义接口
2.接口中可以定义普通方法吗?--在JDK8版本当中不可以
3.接口中可以定义抽象方法,并且都是抽象方法
该类 作为inter接口的实现类
1.实现类如果想要实现接口定义的功能,需要与接口建立关系,
可以通过implements关键字来建立实现类实现接口的关系。
2.如果实现类与接口建立实现关系后可以选择不实现接口中的抽象方法,而是把自己变成一个抽象类;
或者需要实现接口当中的所有抽象方法,把自己变成一个普通子类
接口可以实现实例化吗?---不可以
接口当中是没有构造方法的
3.过程:
1.创建接口Inter---父接口
2.创建接口的实现类interimpl----子实现类
3.创建测试类进行测试
//K.1接口可以继承接口,而且还可以多继承,一个接口继承多个父接口,多个接口之间用逗号分隔;
//K.2实现类与接口是实现关系,并且实现类可以实现多个接口,接口间用逗号隔开,
//对于java中的类而言,遵循单继承,多实现的规则;
//对于java中的接口而言,遵循既可以单继承,也可以多继承规则。
4.关系
1.类与类的关系
继承关系,只支持单继承
2.类与接口的关系
实现关系,既可以单继承,也可以多继承
interface Inte3 extends Inter1{}---接口的单继承
interface Inte4extends Inter1,Inter2{}---接口的多继承
3.接口与接口的关系
是继承,可以单继承,也可以多继承
interface Inter3 extends Inter{} ---接口的单继承
interface Inter4 extends Inter1,Inter2{}---接口的多继承
4.抽象类与接口的区别:
抽象类是一个特殊的类,特殊在,抽象类中可以包含没有方法体的方法(抽象方法)
接口可以理解成一个特殊的抽象类,特殊在,接口里的都是抽象方法,没有普通方法
接口会为方法自动拼接public abstract,还会为变量自动拼接public final static
抽象类可以有成员变量成员常量 接口只能有静态常量
抽象类可以有构造方法–用来给子类创建对象,接口中没有构造方法
抽象类和接口都不能实例化(创建对象)
接口可继承接口,并可多继承接口,但类只能单继承
抽象方法只能声明,不能实现,接口是设计的结果 ,抽象类是重构的结果
5.Object
5.1概念
Object类是所有Java类的祖先,也就是说我们所说的”顶级父类”
它存在于java.lang.Object,这个包不需要我们手动导包
需要注意的是:每个类都使用Object作为超类.所有对象(包括数组)都实现这个类的方法.
在不明确给出超类的情况下,Java会自动把Object类作为要定义类的超类.
5.2 常用方法介绍
toString():本方法用于返回对应对象的字符串表示
打印对象的是println(),这个方法会层层调用,一直到Object中的toString()
Object中toString()的默认实现:对象的名字@十六进制的哈希码值,子类重写了toString()以
后:打印是对象的类型+属性+属性值。
hashCode():本方法用于返回对应对象的哈希码值,哈希码值的得出是通过一种算法,意在让
不同的对象具有不同的哈希码值,用于区分不同的对象.但是有时候也存在不同对象哈希码值相同
的特殊情况,我们称之为”哈希碰撞”现象。
equals():本方法用于指示其他某个对象是否与当前对象”相等”,
Object中equals()的默认实现使用的是==比较 ==比较的是左右两边的值,如果是基本类型,
比较的是字面值,比如1和1,3.4和3.4 如果是引用类型,比较的是引用类型变量保存的地址值。重写后,
不再按照==比较,而是比较两个字符串的具体内容 也就是说,不论创建方式,只要是串的内容一致,
equals()就返回true。
==和equals的区别
1.当使用= =比较时,如果相比较的两个变量是引用类型,那么比较的是两者的物理地值(内存地址),
如果相比较的两个变量都是数值类型,那么比较的是具体数值是否相等。
2.当使用equals()方法进行比较时,比较的结果实际上取决于equals()方法的具体实现
众所周知,任何类都继承自Object类,因此所有的类均具有Object类的特性,比如String、integer等,
他们在自己的类中重写了equals()方法,此时他们进行的是数值的比较,而在Object类的默认实现中,
equals()方法的底层是通过==来实现的。
3.添加重写的equals与hashCode()
equals()与hashCode()逻辑要保持一致,要重写都重写,要不重写都不重写
如果不重写:hashCode()的哈希码根据地址值生成
equals()底层使用==比较两个对象的地址值
* 如果重写了:hashCode()的哈希码根据重写传入的属性值生成
* equals()比较的是重写后类型 + 所有属性与属性值
4.String
4.1 特点String是一个封装char[]数组的对象,字符串不可变,被final修饰,是常量。
String str = “abc”; 等效于:char data[] = {‘a’, ‘b’, ‘c’};
4.2 创建String对象的方式
方式一:
String(char[] value) 分配一个新的 String,使其表示字符数组参数中当前包含的字符序列。
方式二: String str = “abc”;
1.如果是第一次使用字符串,java会在字符串堆中常量池创建一个对象。
2.再次使用相同的内容时,会直接访问堆中常量池中存在的对象。
4.3 常见方法 | String API总结 |
---|---|
int hashCode() | 返回此字符串的哈希码。 |
boolean equals(Object anObject) | 将此字符串与指定的对象比较,比较的是重写后的串的具体内容 |
String toString() | 返回此对象本身(它已经是一个字符串!)。 |
int length() | 返回此字符串的长度。 |
String toUpperCase() | 所有字符都转换为大写。 |
String toLowerCase() | 所有字符都转换为小写 |
boolean startsWith(String prefix) | 测试此字符串是否以指定的元素开头。 |
boolean endsWith(String suffix) | 测试此字符串是否以指定的字符串结束。 |
char charAt(int index) | 返回指定索引/下标处的 char 值/字符 |
int indexOf(String str) | 返回指定字符在此字符串中第一次出现处的索引。 |
int lastIndexOf(String str) | 返回指定字符在此字符串中最后一次出现处的索引。 |
String concat(String str) | 将指定字符串连接/拼接到此字符串的结尾,注意:不会改变原串 |
String[] split(String regex) | 根据给定元素来分隔此字符串。 |
String trim() | 返回去除首尾空格的字符串 |
byte[] getBytes() | 把字符串存储到一个新的 byte 数组中 |
String substring(int beginIndex) | 返回一个新子串,从指定下标处开始,包含指定下标 |
String substring(int beginIndex, int endIndex) | 返回一个新子串,从执定下标开始,到结束下标为止,但不包含结束下标 |
static String valueOf(int i) | 把int转成String |
byte[] bs = s7.getBytes(); | //将指定字符串转为byte[] |
6.StringBuilder/StringBuffer
1 特点
封装了char[]数组
是可变的字符序列
提供了一组可以对字符内容修改的方法
常用append()来代替字符串做字符串连接”+”
内部字符数组默认初始容量是16:super(str.length() + 16);
如果大于16会尝试将扩容,新数组大小原来的变成2倍+2,容量如果还不够,直接扩充到需要的容量大小。
int newCapacity = value.length * 2 + 2;
StringBuffer 1.0出道线程安全,StringBuilder1.5出道线程不安全
2 常见方法
append():使用工具类对象的append()进行拼接。
3 StringBuilder和StringBuffer的区别
1.在线程安全上 :
–StringBuffer是旧版本就提供的,线程安全的。@since JDK1.0
–StringBuilder是jdk1.5后产生,线程不安全的。@since 1.5
2. 在执行效率上,StringBuilder > StringBuffer > String
3.源码体现:本质上都是在调用父类抽象类AbstractStringBuilder来干活,只不过Buffer把代码加了同步关键字,
使得程序可以保证线程安全问题。
正则表达式Regex
1.1 概述:正确的字符串格式规则,常用来判断用户输入的内容是否符合格式的要求,注意是严格区分大小写的。
1.2 常见语法
String提供了支持正则表达式的方法
Matches(正则) : 当前字符串能否匹配正则表达式
replaceAll(正则,子串) : 替换子串
split(正则) : 拆分字符串
身份证号的规律:一共是18位,前17位是数子,第18位有可能是数字,也有可能是X
//String regex = "[0-9]{17}[0-9X]";
/*单个\在Java中有特殊的含义,表示转义符号,不认为是一个斜杠
* 所以如果想要表示斜杠,需要在它的前面加一个用来转义的\
* 也就是\\才表示成一个单纯的斜杠
* \t -- 制表符 \r回车符 \n换行符*/
2 包装类
把基本类型进行包装,提供更加完善的功能。
基本类型是没有任何功能的,只是一个变量,记录值,而包装类可以有更加丰富的功能
2.1 与基本类型的对应关系
2.2 Number
数字包装类的抽象父类。
提供了各种获取值的方式。
2.3 Integer
创建对象
方式一: new Integer(5);
方式二: Integer.valueOf(5);
Integer类中包含256个Integer缓存对象,范围是 -128~127,在此范围内,相同的数据只会存一次,
后续再存都是使用之前存过的数据。
使用valueOf()时,如果指定范围内的值,直接访问缓存对象不新建;如果指定范围外的值,直接新建对象。
Integer有一个高效的效果,但是必须满足3个条件:
* 1.是Integer类型
* 2.使用valueOf()的创建方式
* 3.数据在-128~127的范围内
* 满足以上条件,相同的数据只会存一次,后续再使用都是以前存过的数据。
常见方法
static int parseInt(String s) 将字符串参数作为有符号的十进制整数进行解析
2.5 Double
创建对象
1.new Double(3.14)
2.Double.valueOf(3.14)//和 new 没有区别
常用方法
Double.parseDouble();
只有Integer才有高效的效果Double是没有的
i1是Integer类型的对象,所以可以使用parseInt()将String类型的数据转为int类型 d1是Double类型的对象,
所以可以使用parseDouble()将String类型的数据转为double类型。
表达式 | 格式 |
---|---|
k | 必须匹配指定字符k |
abc | 必须匹配指定字符abc |
[abc] | 匹配单个的字符 |
[abc][123] | 各取一个组合 |
[a-z] | 匹配小写26个字母 |
[a-zA-Z0-9] | 符合3种的都可以存在 |
^a-zA-Z | 排除字母 |
\d | 0–9 |
\D | 排除数字0-9 |
\s | 空白符 |
\S | 排除空白符 |
\w | 数字字母下划线 |
\W | 排除数字字母下划线 |
[abc]?[123] | 1,2,3,a1,a2,a3,b1,b2,b3,c1,c2,c3 |
[abc]* | 可以出现0到多次 |
[abc]+ | 出现次数>=1次 |
[abc]{3} | 元素可以出现3次:aaa,bbb,cab |
. | 单个匹配任意字符 |
$ | 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 ‘\n’ 或 ‘\r’。要匹配 $ 字符本身,请使用 $。 |
( ) | 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 ( 和 )。 |
* | 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 *。 |
+ | 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +。 |
[ | 标记一个中括号表达式的开始。要匹配 [,请使用 [。 |
? | 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 ?。 |
\ | 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, ‘n’ 匹配字符 ‘n’。’\n’ 匹配换行符。序列 ‘\’ 匹配 “”,而 ‘(’ 则匹配 “(”。 |
^ | 匹配输入字符串的开始位置,除非在方括号表达式中使用,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。要匹配 ^ 字符本身,请使用 ^。 |
{ | 标记限定符表达式的开始。要匹配 {,请使用 {。 |
l | 指明两项之间的一个选择。要匹配 |
6.泛型:
1.泛型<?>由来:是JDK1.5的一个新特性,是程序的增强器,是主流的开发方式,模拟数组的检查。
2.泛型通常与集合一起使用,用来约束集合当中元素的类型。
3.泛型的好处:可以约束集合的数据类型,把报错的时机提前,而不是运行时才报错,
在集合中添加元素时会模拟数组的检查。
1.泛型可以实现通用代码的编写,使用E表示元素的类型是Element–元素,
2.泛型的语法要求:如果在方法当中使用范型,必须两处同时出现
一个是传入参数的类型为泛型,一个之返回值前的泛型类型,表示该方法是一个泛型的方法。
常用名称
7.IO流 File 字节流 字符流
IO流:学习父级的公共方法,学习子类对象的创建方式
1.流的分类:
1.1按方向:输入流,输出流。
1.2按操作单位:字节流,字符流。
1.3:组合情况:字节输入流 字节输出流 字符输入流 字符输出流。
字节流:针对二进制文件
字符流针对文本文件
2.字节输入流:
2.1.抽象父级:InputStream---不能实例化对象。
2.2:普通子集:
2.2.1: FileInputStream---操作文件的字节输入流, 构造方法参数:File file/ String pathname。
2.2.2:BufferedInputStream--高效字节输入流
构造方法参数:InputStream,但无法创建抽象父级的对象,所以传的是FileInputStream。
2.2.3.ObjectInputStream--反序列化,用于对象读取readObject(),把之前序列化输出的数据,在程序当中重新输入。把之前序列化输出的文件对象,读取磁盘中序列化的数据,重新恢复对象。
3.字节输出流:
3.1.抽象父级:OutputStream---不能实例化对象。
3.2:普通子集:
3.2.1: FileOutputStream---操作文件的字节输出流: 构造方法参数:File file/ String pathname,默认存在参数boolean append,默认值为false,也就是覆盖输出,若将FileOutputStream构造函数的第二个参数appned设置为true,就会实现输出字节追加的效果。
3.2.2:BufferedOutputStream--高效字节输出流:
构造方法参数:OutputStream,但无法创建抽象父级的对象,所以传的是FileOutputStream。
3.2.3:ObjectOutputStream----序列化,把Java中的对象保存在磁盘当中,相当于将对象信息写出保存到文件当中;序列化输出的数据我们是看不懂的,看起来像乱码,我们需要通过后期的反序列化技术把之前输出的数据重新恢复成对象才能使用。如果本类的对象想要实现序列化输出,必须实现可序列化接口Serializable ;否则会报错:java.io.NotSerializableException: com.jas.serializable.Student。
Serializable是一个空接口,里面没有接口,可以作为标志,标记该类的对象可以被序列化。
4.字符输入流:
4.1.抽象父级:Reader---不能实例化对象。
4.2:普通子集:
4.2.1:FileReader---对文件进行操作的字符输入流:
构造方法参数:File file/ String filename。
4.2.2:BufferedReader---高效字符输入流:
构造方法参数:Reader,但无法创建抽象父级的对象,所以传的是FileReader。
4.2.3:InputStreamReader---
5.字符输出流:
5.1.抽象父级:Writer---不能实例化对象。
5.2:普通子集:
5.2.1:FileWriter---操作文件的字符输出流:
构造方法参数:File file/ String filename,默认存在参数boolean append,
默认值为false,也就是覆盖输出,若将FileWriter构造函数的第二个
参数appned设置为true,就会实现输出字节追加的效果。
5.2.2:BufferedWriter--高效字符输出流:
构造方法参数:Writer,但无法创建抽象父级的对象,所以传的是FileWriter。
5.2.3:OutputStreamWriter---
5.2.4:PrintWriter一行行写出
6.关闭流:关闭流是有顺序的,最后创建的流最先关闭,多条关流语句需要各自try-catch。
六.集合
1.定义:
集合的英文名称是Collection,是用来存放对象的数据结构,而且长度可变,可以存放不同类型的对象,
并且还提供了一组操作成批对象的方法.Collection接口层次结构 中的根接口,接口不能直接使用,
但是该接口提供了添加元素/删除元素/管理元素的父接口公共方法.
2.Java语言的java.util包中提供了一些集合类,这些集合类又称之为容器,
集合类与数组最主要的不同之处是,数组的长度是固定的,集合的长度是可变的,而数组的访问方式比较单一,
插入/删除等操作比较繁琐,而集合的访问方式比较灵活。
方法 | 返回值类型 | 方法描述 |
---|---|---|
add(E e) | boolean | 将指定的对象添加到集合中 |
addAll(Collection c) | boolean | 把小集合添加到大集合当中 |
remove(Object o) | boolean | 将指定的对象从集合当中移除 |
isEmpty() | boolean | 判断当前集合是否为空 |
slze() | int | 返回集合当中的元素个数 |
contains(Object o) | boolean | 判断集合是否包含指定元素 |
toArray() | Object[] | 将集合转化为对象数组 |
iterator | Iterator< E> | 返回集合元素上进行迭代的迭代器,遍历数组中的对象 |
3.常用的集合类有List集合,Set集合,Map集合,其中List集合与Set集合继承了Collection接口,各个接口还提供了不同的实现类。
由于List接口与Set接口都继承了Collection接口,因此这些方法对于List集合和Set集合是通用的.
3.1:List接口
1 概述
有序的colletion(也称为序列).此接口的用户可以对列表中的每个元素的插入位
置进行精确的控制,用户可以根据元素的整数索引(在列表中的位置)来访问元素,并搜索列表中的元素.
2 特点
元素都有下标
数据是有序的
允许存放重复的元素
3 List方法速查表
public List<User> getUserByNA(User user){
List<User> list=new ArrayList<>();
list.add(user);//简化操作,直接返回
list.add(user);
return list;
}
4 ArrayList
4.1 概述
存在java.util包中
内部是用数组结构存放数据,封装数组的操作,每个对象都有下标
内部数组默认的初始容量是10,如果不够会以1.5倍的容量增长
查询快,增删数据效率会低
4.2 创建对象
ArrayList()--构造一个初始容量为10的空序列
原码:int newCapacity=oldCapacity+(oldCapacity>>1);
解释:数组的新容量=旧容量/2的一次方---->相当于原来的1.5倍扩容。
ArrayList扩容
ArrayList相当于在没指定initialCapacity时就是会使用延迟分配对象数组空间,
当第一次插入元素时才分配10(默认)个对象空间。假如有20个数据需要添加,
那么会分别在第一次的时候,将ArrayList的容量变为10;之后扩容会按照1.5倍增长。
也就是当添加第11个数据的时候,Arraylist继续扩容变为10*1.5=15;当添加第16个数据时,
继续扩容变为15 * 1.5 =22个。ArrayList没有对外暴露其容量个数,查看源码我们可以知道,
实际其值存放在elementData对象数组中,那我们只需拿到这个数组的长度,
观察其值变化了几次就知道其扩容了多少次。只能用反射技术获取了。
5 LinkedList
5.1 概述
链表,两端效率高,底层就是链表实现的
5.2 创建对象
LinkedList() 构造一个空列表
5.3 常用方法
void addFirst(E e) 添加首元素
void addLast(E e) 添加尾元素
E getFirst() 获取首元素
E getLast() 获取尾元素
E element() 获取首元素
E removeFirst() 删除首元素
E removeLast() 删除尾元素
boolean offer(E e) 添加尾元素
boolean offerFirst(E e) 添加首元素
boolean offerLast(E e) 添加尾元素
E peek() 获取首元素
E peekFirst() 获取首元素
E peekLast() 获取尾元素
E poll() 返回并移除头元素
E pollFirst() 返回并移除头元素
E pollLast() 返回并移除尾元素
6 扩展:
ArrayList底层是数组结构,查询快.增删慢,适合查询较多的场景
LinkedList底层是链表结构.查询慢,增删快.适合增删操作较多的场景
注意:LinkedList查询慢是指数据量大时,查询中间要慢首位操作还是比较快的
3.2:set接口
1 概述
Set是一个不包含重复数据的Collection
Set集合中的数据是无序的(因为Set集合没有下标)
Set集合中的元素不可以重复 – 常用来给数据去重
2 Set集合的特点
数据无序且数据不允许重复
HashSet : 底层是哈希表,包装了HashMap,相当于向HashSet中存入数据时,会把数据作为K,存入内部的HashMap中。当然K仍然不许重复。
TreeSet : 底层是TreeMap,也是红黑树的形式,便于查找数据
3 常用方法
学习Collection接口中的方法即可
4 HashSet
4.1 概述
底层是哈希表,包装了HashMap,相当于向HashSet中存入数据时,会把数据作为K存入内部的HashMap中,其中K不允许重复,允许使用null.
3.3:.Map接口
1.1 概述
Java.util接口Map<K,V>
类型参数 : K - 表示此映射所维护的键 V – 表示此映射所维护的对应的值
也叫做哈希表、散列表. 常用于键值对结构的数据.其中键不能重复,值可以重复
1.2 特点
Map可以根据键来提取对应的值
Map的键不允许重复,如果重复,对应的值会被覆盖
Map存放的都是无序的数据
Map的初始容量是16,默认的加载因子是0.75
1.3:常用方法
void clear() 从此映射中移除所有映射关系(可选操作)
boolean containsKey(Object key) 如果此映射包含指定键的映射关系,则返回 true
boolean containsValue(Object value) 如果此映射将一个或多个键映射到指定值,则返回 true
Set<Map.Entry<K,V>> entrySet() 返回此映射中包含的映射关系的 Set 视图
boolean equals(Object o) 比较指定的对象与此映射是否相等
V get(Object key) 返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null
int hashCode() 返回此映射的哈希码值
boolean isEmpty() 如果此映射未包含键-值映射关系,则返回 true
Set keySet() 返回此映射中包含的键的 Set 视图
V put(K key, V value) 将指定的值与此映射中的指定键关联(可选操作)
void putAll(Map<? extends K,? extends V> m)从指定映射中将所有映射关系复制到此映射中(可选操作)
V remove(Object key) 如果存在一个键的映射关系,则将其从此映射中移除(可选操作)
int size() 返回此映射中的键-值映射关系数
Collection values() 返回此映射中包含的值的 Collection 视图
2. HashMap
2.1定义
HashMap的键要同时重写hashCode()和equlas()
hashCode()用来判定二者的hash值是否相同,重写后根据属性生成
equlas()用来判断属性的值是否相同,重写后,根据属性判断
–equlas()判断数据如果相等,hashCode()必须相同
–equlas()判断数据如果不等,hashCode()尽量不同
2.2 HashMap的存储过程:
HashMap的结构是数组+链表 或者 数组+红黑树 的形式
HashMap底层的Entry[ ]数组,初始容量为16,加载因子是0.75f,扩容按约为2倍扩容
当存放数据时,会根据hash(key)%n算法来计算数据的存放位置,n就是数组的长度,其实也就是集合的容量
当计算到的位置之前没有存过数据的时候,会直接存放数据
当计算的位置,有数据时,会发生hash冲突/hash碰撞
解决的办法就是采用链表的结构,在数组中指定位置处以后元素之后插入新的元素
也就是说数组中的元素都是最早加入的节点
如果链表的长度>8且数组长度>64时,链表会转为红黑树,当链表的长度<6时,红黑树会重新恢复成链表
七.拓展
1.进程
1.1概念
进程就是正在运行的程序,它会占用对应的内存区域,由CPU进行执行与计算。
1.2 进程的特点
独立性
进程是系统中独立存在的实体,它可以拥有自己独立的资源,每个进程都拥有自己私有的地址空间,
在没有经过进程本身允许的情况下,一个用户进程不可以直接访问其他进程的地址空间
动态性
进程与程序的区别在于,程序只是一个静态的指令集合,而进程是一个正在系统中活动的指令集合,
程序加入了时间的概念以后,称为进程,具有自己的生命周期和各种不同的状态,这些概念都是程序所不具备的.
并发性
多个进程可以在单个处理器CPU上并发执行,多个进程之间不会互相影响.
2 线程
2.1 概念
线程是操作系统OS能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.
一个进程可以开启多个线程,其中有一个主线程来调用本进程中的其他线程。
我们看到的进程的切换,切换的也是不同进程的主线程
多线程可以让同一个进程同时并发处理多个任务,相当于扩展了进程的功能。
2.2 每个线程在共享同一个进程中的内存的同时,又有自己独立的内存空间,
所以想使用线程技术,得先有进程,进程的创建是OS操作系统来创建的,一般都是C或者C++完成
2.3 进程与线程的关系
一个操作系统中可以有多个进程,一个进程中可以包含一个线程(单线程程序),也可以包含多个线程(多线程程序)
2.4 多线程的特性
1 随机性
我们宏观上觉得多个进程是同时运行的,但实际的微观层面上,一个CPU【单核】只能执行一个进程中的一个线程。
那为什么看起来像是多个进程同时执行呢?
是因为CPU以纳秒级别甚至是更快的速度高效切换着,超过了人的反应速度,这使得各个进程从看起来是同时进行的,也就是说,宏观层面上,所有的进程看似并行【同时运行】,但是微观层面上是串行的【同一时刻,一个CPU只能处理一件事】。
2.5 串行与并行
串行是指同一时刻一个CPU只能处理一件事,类似于单车道
并行是指同一时刻多个CPU可以处理多件事,类似于多车道