学习笔记
第一章 Java
Java的特点
1、java语言足够简单,正因为足够简单,所有才能让人们有更多的发挥空间
2、java是一门面向对象的编程语言
3、java是为数不多的多线程编程语言
4、java提供了自动垃圾收集机制,以更好的处理垃圾空间
5、java避免复杂的指针问题,而使用了更加简单的引用来完成内存
匹配
6、java实现任意平台的移植
计算机高级编程语言类型
1、编译型
2、解释型
Java是两种语言的结合
1、编译命令:javac.exe
2、解释命令:java.exe
Java程序组成:java源文件,字节码文件,机器码指令
标识符
类名称、属性名称、方法名称都成为标识符
标识符的基本要求:标识符由字母、数字、—、 符 所 组 成 , 其 中 不 能 以 数 字 开 头 , , 不 能 是 j a v a 中 的 保 留 字 ( 关 键 字 ) 在 编 写 的 时 候 , 尽 量 不 要 去 使 用 数 字 , 命 名 尽 量 有 意 义 , 对 于 符所组成,其中不能以数字开头,,不能是java中的保留字(关键字) 在编写的时候,尽量不要去使用数字,命名尽量有意义,对于 符所组成,其中不能以数字开头,,不能是java中的保留字(关键字)在编写的时候,尽量不要去使用数字,命名尽量有意义,对于有特殊意义,不要使用
Java中的关键字
Abstract boolean break byte ease eath char
Class continue default do double else extends
False final finally float for if implements
Import instanceof int interface lonf native new
Null package private protected public return short
Static synchronized super this throw throws transient
Ture try void volatile while assert enum
Java中有两个未使用到的关键字:goto,const
Java有三个特殊含义标识:ture、false、null
第三章 Java数据类型划分
不同的数据类型可以保存不同的数据内容
Java一共分为两大数据类型:基本数据类型、引用数据类型
1、基本数据类型
1.1、数值型:
整形:byte、short、int、long 默认值:0
浮点型:float、double 默认值:0.0
1.2、字符型:char 默认值:\u000’
1.3、布尔型:boolean 默认值:false
2、引用数据类型:数组、接口 默认值:null
基本数据类型不牵扯内存分配问题,而引用数据类型需要由开发者为其分配空间,而后进行关系匹配
个人选择数据类型原则:
如果想表示整形:int
表示小数:double
描述日期、时间、数字、或表示文件内存大小:long
实现内容传递或者编码转换:byte
实现逻辑控制:boolean
如果想要使用中文:char(避免乱码)
按照保存范围:byte
任何一个数字常量(例如:30、100)那么都属于int类型的数据类型。即:在java之中所有设置的整数内容,默认情况下都是int型数据
所有的变量在同一块代码之中只允许声明一次
在程序的世界里面,数据类型转换有一下规律
1、数据范围小的数据与数据范围大的数据进行数学计算的时候,自动向数据范围大的数据转型后计算;
2、数据范围大的数据要变为数据范围小的数据,必须采用强制转换
3、如果是常量进行强制转换,有两种标记:常量标记(L,l)使用(数据类型)
4、数据大的数据类型也可以转换为数据小的数据类型,这样必须使用“(数据类型)”的格式
小转大:
Int变量 ±long型常量 = long型数据
大转小:
Long num=100;
Int x = (int)num;
如果long变为int时所保存的数据类型超过了int范围,那么依然会出现数据溢出
任意一个整数都属于int型,但是java编译的时候,如果发现使用的数据变量类型为:byte,并且设置的内容在byte范围内,那么就会自动帮助用户实现数据类型转换。反之超过了依然会以 int为主
提示:所有的变量在使用的时候一定不要去相信默认值,都设置具体内容
定义变量的时候直接设置默认值
使用整形就用int,90%以上都适用
1.2浮点型
浮点数就是小数,java之中只要是小数,那么就使用double型数据。double是保存范围最广的数据类型。
由于默认的小数类型是double,所以入股使用了float型,表示需要将double型变为float型,需要强制转换
例如:
Float f1 = 10.2F;
Float f2 = (float)10.2;
所有的数据类型只有double才可以保存小数
1.3字符型;char
Byte是属于字节,按照传统的概念来讲,一个字符等于两个字节,对于字符除了和字节有一些关系之外,最主要的关系在在于int变量的转换
字符可以和int互相转换
‘A’(65)~’Z’(90)
‘a’(97)~’z’(122)
‘0’(48)~’9’(57)
字符与int转换
Char c = ‘A’;
Int num = c;
c = (char)num
1.4布尔型
布尔是一个数学家的名字,布尔型是一种逻辑结果,主要保存有两大数据类型:true、false,这类的数据主要用于一些逻辑判断上
例如:
Boolean flag = ture;
If(flag){
System.out.println(“hello”);
由于设计之初没有考虑到布尔型,那么久使用数字0表示false,而非0表示ture,但是这样的设计对代码开发来说比较混乱,java里面不允许使用0或1来填充布尔型变量内容。那么只能使用false,true
1.5 String型数据
只要是项目开发,100%会使用String,但是与其他基本数据类型相比,String属于引用数据类型(它属于一个类),在java里面只要是类名称,每一个单词首字母都是大写的,但是这个类的使用比较特殊
String 表示的是一个字符串,即:多个字符集,String要求使用“”声明其内容
字符串里面的“+”表示连接操作
任何数据类型加上字符串都是向字符串类型转换
在java里面也支持多种转义字符使用,例如:换行(\n)、制表(\t)、描述\(\)、
双引号(\”)、单引号(\’)
总结:
1、常用的数据类型:整数用:int、小数:double、逻辑:boolean
2、long、byte、char在处理数据的时候回用到
3、数据类型转换用远都是小的数据类型自动向大的数据类型转换,大转小需要强制转换
第四章 Java运算符
Int = 10;
此类方式称为赋值,运算符“=”是实现赋值运算使用的,进行数学计算所使用的四则运算,也属于运算符的定义范畴
在开发之中常使用的积累运算符:四则运算、逻辑运算、三目运算、位运算
简化的运算符: *=、/=、+=、-=、%=
1.1 三目运算:
Int numA=10;
Int numB=20;
Int max=numA > numB?numA:numB;
System.out.println(max);
1.2逻辑运算
与操作
当多个条件使用与进行连接的时候,那么只有多个条件都满足的时候,最终结果才是true,如果有一个条件返回false,那么最终的结果就是false;
单个“=”是赋值,“==”是判断
短路与的使用:
当多个提交件进行与(使用短路与)操作的时候,前面只要有一个条件返回false,那么后面就不在进行判断了,直接返回false;
短路或的使用:
当多个条件进行或(短路或)操作的时候,前面只要有一个条件返回了true,那么后面就不再进行判断力,直接返回true;
总结:
1、运算符写简单的操作
2、三目一定要掌握
3、使用短路与,短路或
第五章 Java程序逻辑控制
1.1程序逻辑控制
程序逻辑主要分为三种逻辑结构:顺序结构、分支结构、循环结构。其中顺序结构最好理解,所有的代码都是有前向后执行的,需要提醒的是顺序是以“{}”为界限的。
分支结构:
分支结构就是一种判断结构。对于分支结构有两类语法支持:if、switch。
If 分支语句:
if If…else If…else if…else ….
If(布尔表达式){
程序语句
} If(布尔表达式){//满足条件时执行
程序语句
}else{//不满足条件是执行
程序语句
} If(布尔表达式1){//满足条件时执行
程序语句
}
If(布尔表达式2){//满足条件时执行
程序语句
}…
Switch语法:
Switch(整数|字符|枚举|String){
Case 内容1:{
满足条件时执行;
Break;
}
Case 内容2:{
满足条件时执行;
Break;
}
Case 内容3:{
满足条件时执行;
Break;
}
Switch只能够判断内容,不能进行布尔表达式的判断
1.2循环语句
有两种循环:while循环、for循环
所有的循环语句必须要有循环初始化条件,每次循环的时候都要修改这个条件,以判断循环是否结束
Do…while循环属于先执行一次,而后在进行判断。即:不管条件是否满足都会执行一次
For循环
For(循环初始化条件;循环判断;循环条件变更){
循环语句;
}
两种语法的选择:
1、如果不知道循环次数,但是知道循环结束条件的时候使用while循环
2、如果已经明确知道了循环次数使用for循环
循环控制:
循环控制有两种语句:continue(退出本次循环)此类语句一定要与判断语句一起使用
Break:退出整个循环
总结:
While循环用于不知道次数,但是知道循环结束条件
For循环用于知道循环次数的循环
Continue和break都需要与if语句结合使用
第六章 方法
方法的基本概念
所谓的方法是指一段可以被重复调用的代码段,利用此操作可以封装执行的代码
在java之中,方法的定义格式比较复杂,所以本次给出的方法有一个要求:指的是定义在主类之中并且由主方法直接调用的方法。方法创建的语法如下:
public static 返回值类型 方法名称(参数类型 变量 、、、){
方法体(本方法要执行的若干操作);
return 返回值;
}
在本定义格式中,发现方法有一个返回值类型,指的是方法方法返回结果,对于此类型有两种:
1、直接设置java中的数据类型(基本数据类型 引用数据类型)
2、方法没有返回值:void
如果方法设置了返回值,那么必须使用return语句返回与之数据类型对应的数据
没有返回值:可以不使用return返回内容,但是可以使用return结束调用
定义方法名称要求:第一个单词首字母小写,而后每个单词首字母大写
在以后的编写代码的时候为了节约代码,可以直接利用方法的返回结果进行输出
如果一个方法使用了void定义为它的返回值,那么可以使用return结束一个方法的调用,但是return不会返回任何内容
只有在方法的返回值为void的前提下才可以使用return结束,使用return结束要与if判断语句一起使用
方法重载
如果说一个方法名称,有可能要执行多项操作,例如:一个add()方法,它可能执行三个整数相加或者可能执行两个小数相加,那么这样的情况下,很明显一个方法体肯定无法满足要求,需要为add()方法定义多个不同的功能实现,所以此类的功能就称为方法的重载,但是在进行方法重载的时候要求方法名称相同,参数类型及个数不同。
方法重载两点说明:
1、在进行方法重载的时候一定要考虑到参数类型的同一,虽然可以实现重载方法返回不同的类型的操作,但是从开发的标准来说,建议所有的重载方法使用同一种返回值类型:
2、方法重载的时候是根据参数类型及个数来区分不同的方法,而不是根据返回值的不同来确定的
方法的递归调用
递归调用是我们迈向数据结构开发的第一步
所谓的递归调用指的就是一个方法自己调用自己的情况,但是如果要想实现自己调用自己,一定需要一个结束的条件,并且每次执行的时候都需要去修改这个结束条件
总结:
1、可以将一些重复执行的代码定义在方法里
2、本次所讲解的方法有它的局限性:定义在主类,并且由主方法直接调用
3、方法的返回值一旦定义了就需要return返回响应数据
4、方法重载(overload)指的是方法名称相同,参数类型及个数不同时,尽量保证返回值类型相同
5、递归调用需要一个结束条件
第七章 面向对象
面向对象:
以一种组件化的形式进行代码的设计,这样开发出来的代码有一个最大的好处,就是重用
在面向对象的程序里面包含有如下的几个特征:
1、封装性:保护内部的定义结构安全性
2、在已有的程序结构上继承继续扩充的新功能
3、多态性:指的是在一个概念范围内的满足
面向对象就是一种组件化思想
类与对象
类与对象是整个面向对象之中最为基础的组成单元,如果需要给出划分定义的话,类就是共性的集合,而对象是一个性的产物。对象能够操作的行为都是有类来决定的,超过了类定义的范畴操作是不能够使用的
类实际上是对象的操作的模板,但是累不能够直接使用,必须通过实例化对象来使用。
类是不能够直接使用的,对象是可以直接使用的,对象是通过类产生的
类与对象的基本定义
如果要在程序中定义类可以使用“class 类名称{}”的语法结构完成,而类之中的组成主要有两点
声明实例化对象:
1、声明并实例化对象: 类名称 对象名称 = new 类名称();
2、声明对象:类名称 对象名称 = null;
实例化对象:对象名称 = new 类名称();
引用数据类型与基本数据类型最大的不同在于需要内存开辟及使用,所有关键字new的主要功能就是开辟内存空间,即:只要是引用数据类型想要使用,那么就必须使用关键字new来开辟空间
当一个对象实例化后那么就可以按照如下的方式利用对象来操作类的结构
1对象.属性:表示要操作类中属性的内容;
2、对象.方法:表示要操作类中的方法
1、堆内存:保存每一个对象的属性内容,堆内存需要使用关键字new才可以开辟;
2、栈内存:保存的时堆内存的地址,但是为了分析方便,可以简单的理解为栈内存保存的是对象名字;
任何情况下只要看见关键字new,都要表示要开辟新的堆内存空间,里面就一定会有所有类中定义的属性,当然所有的属性内柔都是对应数据类型的默认值
引用数据的初步分析
引用是整个java开发之中的核心精髓所在,即:只有掌握了这一基本概念之后,才可以项后面的课程进行深入学习。
在所有的引用分析里面,最关键的还是关键字new,一定要注意的是每一次使用关键字new都一定会开辟一块新的堆内存空间,所以如果你的代码里面声明了两个对象,并且使用了关键字new为两个对象分别实例化操作,那么一定是各自占有各自的堆内存空间,并且不会互相影响。
第八章 深入分析类与对象
封装性
在有private的时候,访问属性的时候发现,外部的对象无法在直接调用类中的属性了,所以现在等于是属性对外部而言就不可见了。
但是如果想要让程序可以正常使用,那么必须想办法让外部的程序可以操作类中的属性才可以,所以在开发之中,针对于属性有这样的以中定义:所有类中的属性都要求使用private声明,如果属性需要被外部所使用,那么按照要求定义相应的setter、getter方法
1、setter方法主要设置内容:public void setTitle(数据类型 变量)有参
2、getter方法主要是取得属性内容:public 数据类型 getTile()无参
总结:
1、封装性就是保证类内部的定义被外部不可见
2、所有的属性必须使用private封装,封装后的属性如果想要被外部访问,要定义setter、getter方法。
构造方法与匿名对象
对象产生的格式:
1、类名称 2、对象名称 = 3、new 4、类名称();
1、类名称规定了对象的类型即:对象可以使用那些属性于方法,都是有类定义的
2、对象名称:如果想要使用对象,需要由一个名字,这是一个唯一标记
3、new:开辟新的堆内存空间,如果没有此语句,对象无法实例化
4、类名称():调用一个和类名称一样的方法,这就是构造方法
通过以上简短的分析发现,所有的构造方法一直被我们调用,但是我们从来没有去定义一个这样的构造方法,之所以能够使用是因为在整个java之中,为了保证程序可以正常执行,那么即使用户没有定义任何的构造方法,也会在程序编译之后自动的为类里面增加一个没有参数、方法名称和类名称相同、没有返回值的构造方法
构造方法定义原则:方法名称与类名称相同,没有返回值
通过代码可以发现,多有的构造方法都是在对象使用关键字new实例化的时候被默认调用的
构造方法与普通方法最大区别?
构造方法是在实例化对象的时候只调用一次
普通方法是在实例化对象产生之后可以被随意调用多次
在实际的工作之中,构造方法的核心作用:在对象实例化时候设置属性的初始化内容,构造方法是为属性初始化准备的
如果一个类中明确的定义了有参构造方法的话,那么不会再默认生成构造方法,即:一个类中至少保留一个构造方法
另外构造方法也属于方法的行列,那么可以对于构造方法进行重载。所以在构造方法重载时,要求只关注参数类型及个数即可
在进行构造方法重载时候有一点代码要求:请按照参数的个数进行升序或降序排列
没有进行构造之前所有属性的值都是对应数据类型的默认值
总结:
1、构造方法定义要求:方法名称与类名称相同,无返回值声明
2、构造方法是在类对象使用关键字new实例化的时候被默认调用的,不管代码如何改变,只要有关键字new,就一定需要构造方法
3、一个类之中至少会保留一个构造方法,如果没有明确的调用构造方法,那么会自动生成一个无参的构造方法
4、构造方法的核心功能是在类对象初始化的时候为类中的属性初始化
5、构造方法重载时,只要求考虑参数类型及个数即可
6、匿名对象只能够调用一次
代码模型
这种功能的类在java开发之中称为简单java类,因为这些类里面不会包含过于复杂的程序逻辑
对于简单java类而言,那么可以给出它第一个开发要求
1、类名称必须存在有意义
2、类之中的所有属性必须封装:private封装后的属性必须提供setter,getter;
3、类之中可以提供多个构造方法,但是必须保留一个无参构造
4、类之中不允许出现任何的输出语句
5、类之中需要提供有一个取得对象完整信息的方法
第九章 数组
数组的基本概念
数组指的是一组相关变量的集合
数组的语法如下:
1、数据类型 数组名称[] = new数据类型[长度]
2、分布完成:
声明数组:数据类型 数组名称[] = null;
开辟数组:数组名称 = new数据类型[长度];
由于数组是一种顺序的结构,并且数组的长度都是固定的,那么可以使用循环方式输出,很明显需要使用for循环,而在java里面为了方便数组输出提供有一个“数组名称.length”的属性,可以取得数组长度。
简化格式:
1、数据类型 数组名称[] = {值,值,…};
完整格式:
2、数据类型 数组名称[] = new数据类型 []{值,值…};
一维数组输出:
public static void pr(int temp[]) {
for(int x = 0;x
}
}
二维数组
在之前的数组里面只有一个“[]”,所以此类数组就是一个普通数组,或者麻烦一点可以把它称为一维数组,如果现在想要描述更多说的数据,那么可以使用二维数组,后面有两个“[][]”
二维数组的定义语法有如下两类:
1、动态初始化:数据类型 数组名称 [][] = new 数据类型[h行的个数][列的个数]
2、静态初始化:数据类型 数组名称 [][] = new 数据类型 [][]{{值,值….},{值,值….}};
二维数组输出:
public static void print(int arr[][]) {
for(int x = 0;x
}
}
}
数组排序:
public static void sort(int arr[]) {
for(int x=0; x< arr.length;x ++) {
for(int y = 0;y < arr.length - 1; y++) {
if(arr[y] > arr[y + 1]) {
int t = arr[y];
arr[y] = arr[y + 1];
arr[y + 1] = t;
}
}
}
}
也可以使用:java.util.Arrays.sort(数组名称);
数组转至:
public static void reser(int []temp) {
int len = temp.length/2;
int head = 0;
int tail = temp.length - 1;
for(int x = 0;x < len;x ++) {
int tem = temp[head];
temp[head] = temp[tail];
temp[tail] = tem;
head ++;
tail --;
}
}
对象数组
数组是引用类型,而类也同样是引用类型,所以如果是对象数组的话表示一个引用类型里面嵌套其他的引用类型
对象数组就是将多个对象交给数组同一管理
总结:
1、对象数组的语法定义 对象数组 = 多个对象
2、数组有一个最大的天生短板:长度固定,所以这就限制了数组在开发之中出现
3、数组排序:java.util.Arrays.sort(数组名称)
第十一章 String类方法
String 类方法
方法名称 类型 功能
1 public String(char[] value) 构造 将字符数组变为String类对象
2 public String(char[] value,
int offset,int count) 构造 将部分字符数组变为String
3 public char charAt(int index) 普通 返回指定索引对应的字符信息
4 public char[] toCharArray() 普通 将字符串以字符数组的形式返回(程序之中索引从0开始)
字节与字符串
5 public String(byte[] bytes) 构造 将全部的字节数组变为字符串
6 public String(byte[] bytes,
int offset,int length) 构造 将部分字节数组变为字符串
7 public byte[] getBytes() 普通 将字符串变为字节数组
8 public byte[] getBytes(String charsetName)throws UnsupportedEncodingException
普通 进行编码转换
字符串的比较
9 public boolean equals(Object anObject)
普通 进行相等的判断,区分大小写
10 public boolean equalsIgnoreCase(String anotherString 普通 进行相等判断,不区分大小写
11 public int compareTo(String anotherString)
普通 判断两个字符串的大小按照字符编码比较
返回值
=0:表示比较的两个字符串内容相等
0:表示大于的结果
<0:表示小于的结果
字符串查找
12 public boolean contains(CharSequence s)
普通 判断指定的内容是佛存在
13 public int indexOf(String str)
普通 后由前向后查找字符串的位置,如果查找到了返回 (一个字母
)位置的索引,找不到返回-1
14 public int indexOf(String str,int fromIndex)
普通 由指定位置从前向后查找指定字符串位置,找不到返回-1
15 public int lastIndexOf(String str)
普通 由后向前查找字符串位置,找不到返回-1
16 public int lastIndexOf(String str,
int fromIndex) 普通 从指定位置由后向前查找指定字符串位置,找不到返回-1
17 public boolean startsWith(String prefix)
普通 判断是否以指定的字符串开头
18 public boolean startsWith(String prefix,
int toffset)
普通 从指定位置开始判断是否以指定的字符串开头
19 public boolean endsWith(String suffix)
普通 判断是否以指定的字符串结尾
字符串替换
20 public String replaceAll(String regex,
String replacement)
普通 全部替换
21 public String replaceFirst(String regex,
String replacement)
普通 替换首个满足条件的内容
字符串截取
22 public String substring(int beginIndex)
普通 从指定索引截取到结尾
23 public String substring(int beginIndex,
int endIndex) 普通 截取部分子字符串的数据
字符串拆分
24 public String[] split(String regex)
普通 按照指定字符串全部拆分
25 public String[] split(String regex,
int limit) 普通 按照指定字符串进行部分拆分
26 public String concat(String str)
普通 字符串连接
27 public String toLowerCase(Locale locale)
普通 转小写
28 public String toUpperCase(Locale locale)
普通 转大写
29 public String trim()
普通 去掉字符串左右两边的空格
30 public int length() 普通 取得字符串长度
31 public String intern()
普通 数据入池
32 public boolean isEmpty() 普通 判断是否是空字符串
字符与字节数组
String str = “hello”;
char c = str.charAt(0);
System.out.println©;
char[] data = str.toCharArray();
for(int x =0;x
}
String st = new String (data);
System.out.println(st);
System.out.println(new String (data,1,3));
字节与字符数组
String str = “helloworld”;
byte[] data = str.getBytes();
for(int x = 0;x < data.length;x ++) {
data[x] -=32;
}
System.out.println(new String(data));
System.out.println(new String(data,0,5));
String sta = “HELLO”;
String stb = “hello”;
System.out.println(sta.compareTo(stb));//只有Stirng类才有大小的判断
字符串查找
String str = “helloworld”;
System.out.println(str.indexOf(“world”));
System.out.println(str.indexOf(“l”));//返回第一个
System.out.println(str.indexOf(“l”,5));
System.out.println(str.lastIndexOf(“l”));
if(str.contains(“world”)) {
System.out.println(“可以查找到数据”);
}
替换
System.out.println(str.replaceAll(“l”,"-"));
System.out.println(str.replaceFirst(“l”,"-"));
字符串截取
System.out.println(str.substring(5));
System.out.println(str.substring(0,5));
字符串拆分
String sta = “hello world nihao mldn”;
String [] result = sta.split(" “);
String [] re = sta.split(” ",2);
for(int x = 0;x < result.length;x ++) {
System.out.println(result[x]);
}
for(int x = 0;x < re.length;x ++) {
System.out.println(re[x]);
}
第十二章 this关键字
在java程序里面它是以“{}”为界限的。如果现在属性名称与参数出现重名的情况下,那么默认的情况下如果没有加入任何限制,指的都是最近的“{}”内容变量名称。所以在这种情况下为了可以明确找到要访问的变量属于类中的属性的时候,需要在变量前面加上this,这样就可以准确的进行属性标记
在以后的程序开发之中,只要是访问类中的属性前面必须加上“this”
调用方法
利用this可以调用普通方法或者构造方法
限制:
1、使用“this”调用构造方法形式只能放在代码的首行
2、进行构造方法互相调用的时候一定要留有出口
也就是说在使用this()互相调用的时候请至少保留一个构造方法没有使用this调用其他构造的情况
表示当前对象:
所谓的当前对象指的就是当前正在调用类方法的对象
总结:
1、类中的属性调用以后都要加上this
2、类中的构造方法间的相互调用,一定要留有出口
3、this表示当前对象,指的是当前正在调用方法的对象,this不是固定的
第十三章 引用传递
引用传递核心意义:同一块堆内存空间可以被不同的栈内存所指向,不同栈内存可以对同一堆内存进行内容的修改
String类对象一旦声明不可改变
package quote;
public class DemoTest {
public static void main(String[] args) {
String msg = "hello";//String一旦声明不可改变
fun(msg);
System.out.println(msg);//hello
}
public static void fun(String temp) {
temp = "world";
}
}
第十六章static关键字
static定义属性
一旦在定义属性的时候使用了static之后,只要有一个对象修改了属性的内容,那么所有对象的static属性一起修改,也就是说此时static定义的属性是全局属性
static属性与非static属性还有一个最大的区别,所有的非static属性必须产生实例化对象之后才可以进行访问,但是static属性不受实例化对象的限制,也就是说在没有实例化对象的情况下依然可以使用static属性
在编写类的过程之中,所选的首先一定不是static属性(95%),如果需要描述共享信息的时候使用static(可以方便集体修改)可以不用重复开辟没存空间。
static定义方法
static定义方法的时候也可以在没有实例化对象的时候直接利用类名称直接调用
static方法与非static方法访问限制
static不能够直接访问非static方法或属性,只能够调用static属性或方法
非static方法可以访问static属性或方法,不受任何限制
为什么会存在这样的限制?
所有的非static属性或方法必须在类已经明确产生了实例化对象才会分配空间,才可以使用
所有的static定义的结构不受实例化对象的限制即:可以在没有实例化对象的时候直接调用
主方法:
public:主方法是程序的开始,所以这个方法对任何的操作都是可见的,那么既然是可见的就必须是有public(公共)
static:证明此方法是由 类名称直接调用的;
void:主方法是一个程序的开始点,既然是所有的开头,那么就不能够回头,执行完毕为止
main:是一个系统规定好的名称不能够修改
String args[]:指的是一个程序运行时传递参数
总结:
1、开发之中首选的一定不是static属性或方法
2、static属性或方法可以在没有实例化对象的时候由类名称直接调用
3、static属性保存在全局数据去
内存区一共有四个:堆内存、栈内存、全局数据区、全局代码区。
第十七章 代码块
普通代码块
普通代码块的作用:防止在方法里面编写的代码变量重复
if(true) {
int num = 10;
System.out.println(“num =” + num);
}
构造块
把代码块写在一个类里面就称为构造块
构造块优先于构造方法执行且如果多次实例化会重复调用
静态块
一个代码使用了static定义就称为静态块分为两种情况
1、非主类静态块:静态块将优先于构造块执行,不管有多少实例化对象,静态块只执行一次,作用:为类中的static属性初始化
2、在主类中的静态块:静态块优先于主方法执行
第十八章 内部类
基本概念
所谓的内部类就是指在一个类的内部继续定义了其他结构类的情况
例如:
class Outer{
private String msg = “hello world”;
class Inner{
public void print() {
System.out.println(msg);
}
}
public void fun() {
Inner in = new Inner();
in.print();
}
}
内部类有一个最大的优点:可以方便访问外部类的私有操作
一旦使用了内部类,私有访问就变得非常简单了
内部类对象实例化语法:
外部类.内部类 对象 = new 外部类().new 内部类();
Outer out = new Outer();
out.fun();
Outer.Inner ine = new Outer().new Inner();
ine.print();
内部类不可能离开外部类的实例化对象,所以一定要先实例化外部类对象后才可以使用内部类对象。如果真的使用到了内部类,也基本上不会像以上的操作那样进行的。一定是通过外部类方问内部类。
static定义内部类
使用了static定义的内部类不受外部类的实例化对象控制
内部类使用了static定义,这个内部类就变为了一个外部类,并且只能访问外部类定义的static操作。相当于定义了一个外部类。
语法:
外部类.内部类 对象 = new 外部类.内部类();
方法中定义内部类
例如:
class Outer {
private String msg = “hello world”;
public void fun(final int num) {
final double sco = 99.9;
class Inner{
public void print() {
System.out.println(Outer.this.msg);
System.out.println(num);
System.out.println(sco);
}
}
new Inner().print();
}
}
总结:
1、内部类只是阐述了基本定义的形式,但是没有讲解如何去使用
2、内部类可以与外部类之间方便的进行私有属性的访问
3、内部类可以使用private声明,声明之后,无法在外部类实例化内部类对象;
语法:
外部类.内部类 对象 = new 外部类().new 内部类();
4、使用static定义的内部类就相当于一个外部类
外部类.内部类 对象 = new 外部类.内部类();
第二十章 继承性
继承的的实现
在java之中如果要想使继承使用extends实现关键字完成,而且实现的语法如下:
class 子类 extends 父类{
一定要记住,子类也叫派生类,父类也叫基类、超类
}
继承的优点:
1、子类可以直接将父类的操作继续使用,属于代码重用
2、子类可以继续扩充自己的方法
继承的限制
利用extends关键字在大部分的情况下都可以不用去考虑(前提:按照标准格式开发),但是事实上由于要限制用户的使用,所以继承也有自己的一些要求
1、java不允许多重继承、允许多层继承
2、子类在继承的时候严格来讲会继承父类中的全部操作,但是对于所有的隐式继承,而所有的非私有操作属于显示继承
所有的private操作不能直接使用,多有的非私有操作可以直接使用
子类一定存在私有属性,不能直接使用,但是可以利用父类中的方法操作属性
3、子类对象构造之前一定会默认调用父类的构造(默认调用无参构造)以保证父类对象先实例化,而后在实例化子类对象
如果父类中没有无参构造方法,那么久必须使用“super()”明确调用父类的有参构造
通过代码验证:super()与this()不能同时出现,不管子类怎么折腾,他永恒有一个前提:子类对象执行前一定要先执行父类构造,为父类对象初始化后,才轮到子类对象实例化
第二十一章 覆写
方法的覆写
当子类定义了与父类方法名称相同,参数类型及个数、返回值类型相同时就称为方法的覆写
覆写后关于方法调用的说明:
当发生覆写之后,此时会调用实例化子类中已经被覆写的方法
一个类会产生多个子类,那么每一个子类都一定或有自己的实现
覆写结果分析要素:
1、观察实例化的是哪个类
2、观察实例化类里面调用的方法是否被覆写过,如果每有覆写调用父类的方法
覆写的使用原则:
如果现在发现父类中的方法名称工能不足(不适合本子类),但是又必须使用此方法名称时候,就需要覆写这一概念
以上的代码确实已经实现了覆写的功能,但是如果要想更好的实现覆写的操作,还必须考虑到权限的问题,被子类覆写的方法不能够拥有比父类更为严格的控制权限
对于访问控制权限已经学习过三个:public >default>private ,也就是说private的访问权限是最为严格的,即:如果父类的方法使用的是public声明,那么子类覆写此方法的时候,只能是public,如果父类的方法是default,那么子类可以使用public、default。99%的情况下方法都是用public
使用private定义的方法,这个时候发现子类中根本没有覆写使用private定义 的方法,也就是说如果使用了private声明,那么这个方法对于子类是不可见的,就算子类定义了完全符合覆写要求的方法,那么也不能够发生覆写,这个时候子类的方法实际上就是子类自己定义的方法
一旦有了覆写之后,默认情况下,子类所能够调用的一定是覆写过得方法。为了能够明确的由子类调用父类中已经被覆写的方法,那么可以使用“super.方法()”来进行访问。
关于super.方法()与this.方法()的区别?
使用this.方法()会首先从本类中查找是否存在要调用的方法名称,如果存在则直接调用,如果不存在则查找父类中是否存在,如果有就调用,没有就包编译时错误
使用super.方法().明确的表示调用的不是子类中的方法,而直接调用父类的方法。
总结:
覆写必须保证返回值类型相同。
第二十三章 final关键字
在java之中final称为终结器,在java里面可以使用final定义类,方法、属性。
1、使用final定义的类不能够再有子类
2、使用final定义的方法不能被子类所覆写
3、使用final定义的变量就成为了常量,常量必须在定义的时候设置好内容,并且不能修改
特别需要隆重介绍的是全局常量:public static final声明的就是全局常量
为了让程序中的常量可以与变量有效的进行区分,所有的常量名称都要求使用大写字母表示。
总结:
1、在以后查看文档的时候,如果发现了final定义的类或方法时,千万不要继承或覆写。
2、使用public static final定义的是全局常量,全局常量每一个字母都要求大写。
对象的多态性
多态性严格来讲只能为其讲解基本概念,以及相关的使用限制
多态性的依赖:方法的覆写;
多态性严格来讲有两种描述方式;
1、方法的多态性
方法的重载:同一个方法名称,会根据传入的参数类型及个数不同,会执行不同的方法体
方法的覆写:同一个方法会根据子类的不同,实现不同的功能
2、对象的多态性:指的是在继承关系之中,子类和父类之间的转换
向上转型:父类 父类对象 = 子类实例;
向上转型:由于所有的子类对象实例都可以自动的向上转型,多以这个代码的最大的意义在于参数类型的同一上,参数类型同一后,还可以调用子类覆写后的方法体,即:同一方法针对于不同的子类有不同的实现
向下转型:子类 子类对象 = (子类)父类实例;
向下转型:指的是父类调用子类的特殊方法:所有的父类发生了转型之后,只能够看见自己定义的全部方法信息,但是看不见子类的特殊方法,此时就需要向下转型,将父类对象转化为子类对象,这样就可以使用子类的特殊功能
对于对象的转型给出以下的经验总结
80%的情况都只会向上转型同时可以得到参数类型的同一方便于我们的程序设计:子类定义的方法大部分情况下请以父类的方法名称为标准准确覆写,不要过多的扩充方法
5%的情况下会使用向下转型,目的调用子类的特殊方法:
15%的情况下是不转型:例如:String
个性化的操作在一个标准的开发之中应该尽量少出现,因为对象的转型操作里面毕竟有了强制问题,容易带来安全隐患
为了保证转型的顺利进行,在java里面提供有一个关键字instanceof,此关键字的使用:
对象 instanceof 类返回boolean
总结:
1、开发之中尽量使用向上转型,以确定参数类型同一,同时发生向上转型之后才可以发生向下转型
2、子类尽量不要扩充过多的与父类无关的操作方法
90%的情况下子类的功能要与父类的方法功能一致
第二十四章 抽象类
所谓的抽象类就是指在普通类里面增加抽象方法的组成部分
抽象方法:指的是没有方法体的方法,同时抽象方法还必须使用abstract关键字进行定义
抽象类的使用原则如下:
1、抽象类必须有子类,即:每一个抽象类必须被子类继承
2、抽象类的子类必须覆写抽象类中的全部抽象方法(强制子类覆写),子类不是抽象类
3、抽象类的实例化对象需要依靠子类完成,采用向上转型的方式处理
总结:
1、抽象类继承子类里面会有明确的方法覆写要求,而普通方法并没有
2,抽象类只是比普通类多了一些抽象方法的定义,其他的组成部分与普通类完全一样
3、普通类可以直接实例化,但是抽象类的对象必须经过向上转型之后才可以得到实例化对象
一个子类只能继承一个抽象类
抽象类的相关限制
1、抽象类里面会存在一些属性,那么抽象类之中一定会存在构造方法,目的为属性初始化,并且子类对象实例化的时候依然满足于先执行父类构造,在执行子类构造
2、抽象类不能够使用final定义
3、外部的抽象类不允许使用static声明,而内部的抽象类允许使用static声明,使用static声明的内部抽象类就相当于是一个外部抽象类,继承的时候会使用外部类.内部类的形式表示类名称
4、任何情况下,如果执行类中static方法的时候,都可以在没有对象的时候直接调用,对于抽象类也是一样
5、有些时候,由于抽象类只需要一个特定的系统的子类操作,所以可以忽略掉外部子类。这样的设计在系统类库之中会比较常见,目的为用户隐藏不需要知道的子类
在任何一个类的构造执行完毕之前,所有属性都是其对应数据类型的默认值,而子类的构造执行之前一定先执行父类的构造。
第二十五章 接口
接口的基本定义
如果一个类之中只是由抽象方法和全局常量所组成的,那么这种情况下将不会将其定义为一个抽象类,而只会讲其定义为接口,所谓的接口严格来讲就属于特殊的抽象类,而这个类里面只有抽象方法和全局常量
要定义接口使用interface关键字完成
例如:
interface A{
public static final String MSG = “hello”;
public abstract void print();
}
由于接口里面存在有抽象方法,所以接口对象不能直接使用关键字new进行实例化对象的操作,所以接口的使用原则如下:
1、接口必须有子类,但是此时的子类可以使用implements关键字实现多个接口
2、接口的子类(如果不是抽象类),必须覆写接口中的全部抽象方法
3、接口的对象可以利用子类的向上转型进行实例化操作。
接口可以实现多继承:
class X implements A,B
抽象类和接口一起实现:
class D extends C implements AA,BB
接口中的方法可以简写:
public 数据类型 方法名称();
对于接口的组成,99%的情况下都是以抽象方法为主的。很少情况下接口只有全局常量
一个抽象类可以继承一个抽象类,但是反过来一个接口可以利用entends关键字同时继承多个接口(接口不能继承抽象类)
从继承关系上来讲抽象类要比接口限制多了很多
一个抽象类只能够继承一个抽象的父类,而接口没有这个限制
一个子类只能够继承一个抽象类,而却可以实现多个接口
在整个java里面,接口的主要功能就是解决单继承局限
在开发之中接口的三大核心作用:
定义不同层次之间的标准
表示一种操作能力
表示将服务器端的远程方法视图暴露给客户端
标准:
interface USB {
public void start();
public void stop();
}
class Computer {
public void plugin(USB usb) {
usb.start();
usb.stop();
}
}
class Flash implements USB {
@Override
public void start() {
System.out.println("u盘开始工作");
}
@Override
public void stop() {
System.out.println("u盘开始工作");
}
}
class Print implements USB{
@Override
public void start() {
System.out.println("打印机开始工作");
}
@Override
public void stop() {
System.out.println("打印机停止工作");
}
}
class MP3 implements USB{
@Override
public void start() {
System.out.println("mp3开始工作");
}
@Override
public void stop() {
System.out.println("mp3停止工作");
}
}
public class DE {
public static void main(String[] args) {
Computer com = new Computer();
com.plugin(new Flash());
System.out.println();
com.plugin(new Print());
System.out.println();
com.plugin(new MP3());
}
}
工厂设计模式:
package Interface;
interface Fruit{
public void eat();
}
class Apple implements Fruit{
@Override
public void eat() {
System.out.println("吃苹果");
}
}
class Orange implements Fruit{
@Override
public void eat() {
System.out.println("吃橘子");
}
}
class Factory {
public static Fruit getInstance(String className) {
if(“apple”.equals(className)) {
return new Apple();
}else if(“orange”.equals(className)) {
return new Orange();
}else {
return null;
}
}
代理设计模式:
package Interface;
interface Subject{
public void make();
}
@SuppressWarnings(“rawtypes”)
class RealSub implements Subject{
public void make() {
System.out.println(“真是主题”);
}
}
class Project implements Subject{
private Subject sub;
public Project(Subject sub) {
this.sub = sub;
}
public void prepare() {
System.out.println("为真是主题做准备");
}
@Override
public void make() {
this.prepare();
this.sub.make();
this.destrot();
}
public void destrot() {
System.out.println("收尾工作");
}
}
第二十六章 Object类
Object类的基本作用
Object是所有类的父类。也就是说任何一个类在定义的时候如果没有明确的继承一个父类的话,那么他就是Object类的子类
既然Object类是所有类的父类,那么最大的好处就在于:利用Object可以接受全部类的对象,因为可以向上自动转型
为什么在Object类里面要定义一个无参构造
既然Object类是所有类的父类,那么所有类实例化对象的时候,子类构造方法执行前一定要默认执行父类的无参构造
从严格意义上来讲(一般不遵守),任何一个简单java类都应该覆写Object类的三个方法:
取得对象信息:public String to String() ;
取得对象比较:public boolean equals (Object obj) ;
取得对象哈希码:public int hashCode() ;
直接输出对象就相当于调用了toString()方法
第二十七章 扩展概念
匿名内部类
interface Mesg{
public void print();
}
public class Ga {
public static void main(String[] args) {
fun(new Mesg() {
public void print() {
System.out.println("hello");
}
});
}
public static void fun(Mesg msg) {
msg.print();
}
}
使用匿名内部类有一个前提:必须基于接口或抽象类的应用
认识包装类
java在设计之初有一个基本原则:一切皆对象,一切的操作的形式进行描述。但是这里就会出现一个矛盾,基本数据类型不是对象。
在java里面为了方便用户的使用,所以转门提供了一组包装类,来包装所有的基本类型:
byte(Byte)、short(Short)、int(Integer)、long(Long)、float(Float)、double(Double)、char(Characte)、boolean(Boolean)
以上给出的包装类又分为两种类型:
对象包装类:Characte、Boolean
数值包装类:(Number直接子类):Byte、Short、Integer、Long、Float、Double
Number是一个抽象类,里面定义了六种操作方法:intValue()、doubleValue()、floatValue()、byteValue()、shortValue()、longValue()
装箱与拆箱操作
1、装箱操作:将基本数据类型变为包装类的形式
每个包装类的构造方法都可以接受各自数据类型的变量
2、拆箱操作:从包装类中取出被包装的数据
利用Number类中提供的一系列的:xxxValue()方法完成
数据类型转换
包装类的最多的情况下实际上是它的数据类型转换上,在包装类里面提供有将String型数据类型变为基本数据类型的方法:
Integer类:public static int parseInt(String s)
Double类:public static double parseDouble (String s)
Boolean类:public static boolean parseBoolean (String s)
String str = “123”;
int m = Integer.parseInt(str);
System.out.println(m);
String sta=“10.2”;
double b = Double.parseDouble(sta);
System.out.println(b);
String bo =“true”;
boolean va = Boolean.parseBoolean(bo);
System.out.println(va);
基本数据类型变为字符串:public static String valueOf(数据类型 变量)
Integer im = 10;//自动装箱
int i = im;//自动拆箱
System.out.println(i);
在使用包装类的时候,很少利用构造方法完成,几乎都是利用直接赋值的方式完成,但是在判断内容是否相等的时候要用equals()方法
Object此时可以统一天下了
Object可以接受一切的引用数据类型,由于存在有自动装箱与拆箱的机制,那么Object可以存放基本数据类型了
流程:基本数据类型—>自定装箱(称为对象)—>向上转型称为Object
例如:
Object oo = 10;
int tt = (Integer)oo;
System.out.println(tt);
总结:
字符串与基本数据类型转换:
字符串变为基本数据类型,包装类的parseXxx()方法
基本数据类型变为字符串依靠:ValueOf(数据类型 变量)
第二十九章 访问控制权限
在java里面支持四种访问控制权限。public、protected、default、private
no 范围 public protected default private
1 在同一个类中 可以访问 可以访问 可以访问 可以访问
2 在同一包中的不同类 可以访问 可以访问 可以访问
3 在不同包的子类里面 可以访问 可以访问
4 在不同包的非子类里面 可以访问
名称要求:
类名称每一个单词的首字母大写,其余小写
属性名称第一个单词字母小写,其余首字母大写
方法名称第一个单词字母小写,其余首字母大写
常量名称全部大写
构造方法私有化
单例设计模式
class Singleton{
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
}
public void print() {
System.out.println("hello world !!!");
}
public static Singleton getInstance() {
return INSTANCE;
}
}
作用:让一个类在一个系统里面只允许有一个实例化对象
第三十三章 java 5新特性
可变参数
例如:
public static int add(int … tem) {
int sum =0;
for(int x = 0;x < tem.length;x ++) {
sum +=tem[x];
}
return sum;
}
System.out.println(add(10,2,2,6,54,87,7));
增强型for循环
语法如下:
for(类型 变量 :数组 |集合){
//次循环会自动的将数组的内容设置给变量
}
int[] data = new int[] {1,2,3,4,5,6,7,8,9};
for(int y:data) {
System.out.println(y);
}
总结:
foreach循环支持数组的直接访问,避免了索引访问带来的麻烦
第四十六章 正则表达式
正则标记
1、单个字符(数量:1)
字符:表示由一个字符组成
\:表示转义字符“\”
\t:表示一个“t”
\n:表示匹配换行
2、字符集(数量:1)
[abc]:表示可能是字符a、b、c中的任意一位字符
第四十七章 反射机制
1.1 认识反射
反射的话先通过“反”来理解,既然有“反”就一定有“正”,在正常情况下,一定是先有类。而后才有对象。
所谓的“反”就是指可以利用对象找到对象的出处,在object类提供有一个方法
取得class对象:public final Class> getClass()
发现调用了getClass()方法后的就输出了类的完整名称,等于是找到了对象的出处。
1.2 Class类对象实例化
Java.lang.Class是一个类,这个类是反射操作的源头。即:所有的反射都要从此类开始进行,而最关键的是,这个类有三种实例化方式:
. 第一种:调用object类中的getClass() :
Date date = new Date();
Class> cls = date.getClass();
.第二种:使用“类.class”取得:
Class> cls = Date.class;
.第三种:调用class类提供的一个方法:
-实例化Class对象:publicstatic Class> forName(String className)
throws ClassNotFoundException
Class> cls = Class.forName(“java.util.Date”);
1.3反射实例化对象
当拿到一个类的时候,肯定要直接使用关键字new进行对象实例化,这属于习惯性做法,但是如果有了Class类对象,那么就可以做到利用反射来实现对象实例化操作:
实例化对象方法:public T newInstance()throwsInstantiationException,
IllegalAccessException
Class> cls = Class.forName(“fsjz.Book”);
Object obj = cls.newInstance();
Book book = (Book) obj;
System.out.println(book);
有了反射之后,以后实例化对象的操作不在只是单独的依靠关键字new完成了,反射也同样可以完成,但是这并不表示new就被完全却代了。
在任何开发之中,new是造成耦合的最大元凶,一切的耦合都来源与new。
1.4 使用反射调用构造
在Class类里面提供有一个方法可以取得构造:
.取得全部构造:public Constructor>[] getConstructors()
throws SecurityException
.取得一个指定参数顺序的构造:public Constructor getConstructor(Class>... parameterTypes)
throws NoSuchMethodException, SecurityException
以上两个方法返回的都是“java.lang.reflect.Constructor”类的对象。在这个类中提供有一个明确传递有参构造内容的实例化对象方法:
public T newInstance(Object… initargs)throwsInstantiationException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException
Class> cls = Class.forNmae(“cn.Book”);
Constructor> con = cls.getConstructor(String.class,double.class);
Object obj = con.newInstace(“java开发”,79.8);
System.out.println(obj);
1.5 反射调用方法
在Class类里面提供有一下取得类中方法的操作:
.取得一个类中的全部方法:public Method[] getMethods()
throws SecurityException
.取得指定方法:public Method getMethod(String name,
Class>... parameterTypes) throws NoSuchMethodException,
SecurityException
.以上的两个操作返回了” java.lang.reflect.Method”对象
. 调用方法:public Object invoke(Object obj, Object… args)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException
第五十章 字节流与字符流
学习原则:抽象类中定义的抽象方法会根据实例化的其子类的不同,也会完成不同的功能
五个核心类:File、InputStream、OutputStream、Reader、Writer
一个核心接口:Serializable
File类是唯一一个与文件本身操作有关的类,但是不涉及到文件的具体内容(只能创建、删除)
构造方法:public File(String pathname);设置完整路径(重要)
构造方法:public File(File parent,String child);设置父路径与子文件路径
创建文件:public boolean createNewFile()throws IOException;
删除文件:public boolean delete();
判断文件是否存在:public boolean exists()
判断是否是目录:public boolean isDirectory()
判断是否是文件:public boolean isDirectory()
找到父路径:public File getParentFile()
创建多级目录:public boolean mkdirs()
File file = new File(“e:” + File.separator + “demo” + File.separator + “na.txt”);
if(!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
if(file.exists()){
file.delete();
}else{
System.out.println("file.createNewFile());
}
取得文件内容信息大小:public long length()
inputStream
字节输入流:InputStream(读取内容到终端)
定义
public abstract class InputStream extends Objectimplements Closeable
数据读取的方法
读取单个字节:public abstract int read()throws IOException
-返回值:返回读取的字节内容,如果发现已经没有内容,返回 -1
将读取的数据保存在字节数组里:public int read(byte[] b)throws IOException
-返回值:返回读取的数据长度,如果已经读取到结尾了返回 -1
将读取的数据保存在部分字节数组里:public int read(byte[] b,int off,int len)throws IOException
-返回值:读取的部分数据长度,如果已经读取到结尾了返回 -1
InputStream是一个抽象类,如果要想进行文件读取使用用FileInputStream子类进行实例化
构造方法:public FileInputStream(File file)throws FileNotFoundException
outputStream
字节输出流:OutputStream(输出内容到文件上)
字节流:InputStream、OutputStream
字符流:Reader、Writer
字节输出流(OutputStream)是抽象类
OutputStream是一个专门字节数据输出的一个类
定义
public abstract class OutputStream
extends Object
implements Closeable, Flushable
关闭资源方法:public void close()throws IOException
刷新:public void flush()throws IOException
输出方法
输出单个字节:public abstract void write(int b)throws IOException;
输出全部字节数组:public void write(byte[] b)throws IOException;
输出部分字节数组(最重要):public void write(byte[] b,int off,int len)throws IOException;
需要用到FileOutputStream子类
定义
public class FilterOutputStream
extends OutputStream
创建或覆盖已有文件:public FileOutputStream(File file)throws FileNotFoundException;(最重要)
进行文件追加:public FileOutputStream(File file,boolean append)throwsFileNotFoundException;
reader
Reader(输出到终端)
Reader是进行字符数据读取的输入流其本身也是一个抽象类
定义
public abstract class Reader extends Object implements Readable, Closeable
读取内容到字符数组:public int read(char[] cbuf)throws IOException
-返回值:表示读取的数据长度,如果已经读取到结尾返回 -1
Reader类实例化的时候可以使用FileReader子类完成
字节流与字符流最大的区别是,字节流直接与终端进行数据交互,而字符流需要将数据经过缓冲区处理后才可以输出
在使用OuputStream输出数据的时候即使最后没有关闭输出流,那么内容也可以正常输出,但是反过来如果使用的是字符输出流,如果不关闭那么就表示在缓冲区之中处理的内容不会被强制性清空,所以就不会输出数据。如果有特殊情况不能关闭字符输出流,可以使用flush()方法强制清空缓冲区
字符流最大的好处可以进行中文的有效处理
writer
字符输入流(输出内容到文件上)
可以输出字符串
定义
public abstract class Writer extends Object implements Appendable, Closeable, Flushable
输出全部字符数组:public void write(char[] cbuf)throws IOException
输出字符串:public void write(String str)throws IOException
Writer 是一个抽象类,如果要想为这个类的对象实例化,应该使用FileWriter子类;
构造方法:public FileWriter(File file)throws IOException
构造方法:public FileWriter(File file,boolean append)throws IOException
File file = new File(“E:” + File.separator + “mydemo” + File.separator + “na.txt”);
if(!file.getParentFile().exists()) {//目录不存在
file.getParentFile().mkdirs();//创建目录
}
Writer wr = new FileWriter(file);
String str = “千万不要被节后综合征打败”;
wr.write(str);//直接进行字符串输出
第五十六章 类集框架
类集简介
类集就是一组java实现的数据结构。所谓的类集就是对象数组的应用
类接的接口:
Collection、List、Set
Map
Iterator、Enumeration
类集就是java数据结构实现,类集就是动态的对象数组
Collection接口
Collection是整个是整个类集之中最大的父接口。即:每一次可以向集合里保存一个对象
定义:public interface Collection extends Iterable
No 方法名称 类型 作用
1 public boolean add(E e)
普通 向集合里保存数据
2 public boolean addAll(Collection extends E> c)
普通 追加一个集合
3 public void clear() 普通 清空集合
4 public boolean contains(Object o)
普通 判断是否包含指定内容
5 public boolean isEmpty() 普通 判断是否是空集合
6 public boolean remove(Object o)
普通 删除
7 public int size() 普通 取得集合中保存的元素个数
8 public Object[] toArray()
普通 将集合变为对象数组保存
9 public Iterator iterator()
普通 为Iterrator对象实例化
在所有的开发之中add()与iterato()两个方法使用的几率是最高的,其他方法机乎可以忽略
List子接口
list子接口的常用子类(ArrayList、Vector)
List子接口(80%)是Collection中最为常用的一个子接口,有扩充方法
No 方法名称 类型 作用
1 public E get(int index) 普通 取得指定索引编号内容
2 public E set(int index,E element) 普通 修改指定索引编号内容
3 public ListIteraton listIterator() 普通 为listIterator接口实例化
总结:
1、list中的数据保存顺序就是数据添加顺序
2、list集合可以保存重复元素
3、list接口比Collection接口扩充了get()方法
4、list选择子类就使用ArrayList子接口
set子接口 常用HashSet TreeSet
set集合下没有重复元素(这一点是set接口特征),同时发现set接口保存数据是没有任何顺序的,即:HashSet子类的特征属于无序排序
TreeSet保存内容自动排序
以后再非排序情况下,只要是判断重复元素依靠的用远都是hashCode()与equals()
HashSet无序
TreeSet有序
集合输出
在jdk1.8之前支持四种输出:Iterator(95%)、ListIterator(0.05%)、Enumeration(4.9%)、foreach(0.05%)
迭代输出
如果遇见了集合操作,那么一般而言都会使用Iterator接口进行集合输出操作
Interface Iterator{
public boolean hasNext();//判断是否有下一个元素
public E next();//取出当前元素
}
双向迭代
判断是否有前一个元素:public boolean hasPrevious();
取得前一个元素:public E previous();
ListIterator是专门为list子接口定义的输出接口
方法:
public ListIterator listIterator();
双向迭代一定要发生由前向后输出
foreach输出
例如:
List all = new ArrayList();
all.add(“hello”);
all.add(“world”);
all.add(“nihao”);
for(String str:all) {
System.out.println(str);
}
Enumeration输出
定义:Interface Enumeration{}
判断是否由下一个元素:
public boolean hasMoreElements()
取出当前元素:boolean hasMoreElements()
Map接口
map可以保存键值对形式的数据
常用方法:
public V put(K key, V value):向集合中保存数据
public V get(Object key):根据key查找对应的value
public Set
public Set keySet():取出全部的key
常用子类:HashMap、Hashtable
使用HashMap定义的Map集合是无序的
发现重复的key会进行覆盖,使用新的内容替换旧的内容
Map接口中有get()根据key查找value
HashMap允许数据设置为空,Hashtable不允许数据设置为空
Map集合利用Iterator接口输出的步棸
1、利用Map接口的entrySet()方法将Map集合变为Set集合,里面的泛型是Map.Entry
2、利用Set集合iterator()方法将Set集合进行Iterator输出
3、每一次Iterator循环取出Map.Entry接口对象,利用此对象进行key与value的取出
在以后使用Map集合的时候,首先的key类型是String
总结:
1、map集合保存的数据是为了查询使用,而Collection保存数据是为了输出使用
2、Map使用Iterator接口输出的步棸与具体实现代码
3、HashMap可以保存null,key重复符会覆盖
Stack子类(先进后出)
Stack表示的时栈操作,栈是一种先进后出的数据结构,而stack是vector子类
入栈:public E push(E item);
出栈:public E pop();
Properties子类
Properties是Hashtable子类
设置属性:public Object setProperty(String key,String value)
取得属性:public String getProperty(String key)
第三十七章 java8新特性
接口定义的增强
在接口里面可以使用default定义普通方法
也可以使用static定义方法直接有接口名称调用
Lamda表达式
前提条件匿名内部类
例如:
interface IMessage{
public void print();
}
public class TE {
public static void main(String[] args) {
fun(()->System.out.println("hello world !"));
}
public static void fun(IMessage msg) {
msg.print();
}
}
对于Lamda表达式的语法有三种形式:
(参数)->单行语句:
(参数)->{单行语句};
(参数)->表达式。
方法引用
所谓的方法引用就是指为一个方法设置别名,相当于一个方法定义了不同的名字
在java8之中一共定义了四种形式:
引用静态方法:类名称::static方法名称
引用某个对象的方法:实例化对象::普通方法
引用特定类型的方法:特定类::方法(普通方法)
引用构造方法:类名称::new
函数式接口
1、功能性接口(Function):Interface Function
此接口需要接受一个参数,并且返回一个处理结果
2、消费型接口(Consumer):Interface Consumer{public void accept(T t);}
此接口只是负责接受数据(引用数据是不需要返回),并且不返回处理结果
3、供给型接口(Supplier):Interface Supplier{public T get();}
此接口不接收参数,但是可以返回结果
4、断言型接口(Predicate):Interface Predicate{public boolean test(T t);}
进行判断操作使用
第三十八 java多线程的实现
线程与进程
在操作系统的定义之中,进程指的是一次程序的完整运行,在这个运行过程之中,内存处理器、IO等资源操作都要为这个进程服务
线程是在进程基础上进一步划分的结果,即一个进程上可以同时创建多个线程
线程是比进程更快的处理单元,而且占用资源也小。那么多线程的应用就是性能最高的应用
总结:线程离不开进程。进程如果消失后线程一定会消失,反之线程消失了,进程未必消失了
多线程的实现
如果想要在java之中实现多线程有两种途径:
继承Thread类:
实现Runnable接口(Callable接口);
继承Thread类:
Thread类是一个支持多线程的功能类,只要有一个子类就可以实现多线程支持
所有程序的起点是main()方法,但是多有的进程也一定要有一个自己的起点,那么这个起点就是run()方法,也就是所在多线程的每个主体类之中都必须覆写Thread类之中提供的run()方法
public void run();
启动多线程
public void start():调用此方法执行的方法体是run()定义的
实现Runnable接口
定义:
@FunctionalInterface
public interface Runnable
不管何种情况下,如果要想启动多线程一定依靠Thread类完成
public Thread(Runnable target):接受Runnable接口对象
以后用Runnable实现线程主体类,用Thread启动多线程
请解释Runnable接口和Thread类实现多线程的区别?
Thread类是Runnable接口的子类,使用Runnable接口实现多线程可以避免单继承局限
Runnable接口实现多线程可以比Thread类实现多线程更加清楚的描述数据共享的概念
第三十九章 多线程的常用操作方法
线程的命名与取得
如果想要进行多线程名称操作,可以使用Thread类的如下方法:
构造方法:public Thread(Runnable target,String name);
设置名字:public final void setName(String name);
取得名字:public final String getName();
取得当前线程对象:public static Thread currentThread();
线程的休眠
所谓的线程休眠指的就是让线程执行的速度变慢一点。休眠方法:public static void sleep(long millis);这个方法有异常抛出
因为每次执行到run()方法的线程对象都必须进行休眠,所以执行速度会变慢。
默认情况下,在休眠中如果设置了多个对象,那么多有的线程对象将一起进入到run()方法(所谓的一起休眠是因为先后顺序太短了,但是实际上有区别)
线程的优先级
多为的优先级指的是优先级越高越有可能先执行。在Thread类里面提供有一下的两个方法进行优先级操作
设置优先级:public final void setPriority(int newPriority)
取得优先级:public final int getPriority()
发现设置和取得优先级都适用了int数据类型,对于此内容有三种取值;
最高优先级:public static final int MAX_PRIORITY
中等优先级:public static final int NORM_PRIORITY
最低优先级:public static final int MIN_PRIORITY
第四十章 线程的同步与死锁
同步问题的引出
所谓的同步指的是多个线程访问统一资源的时所需要考虑的问题
同步操作
在java里面如果想实现线程同步可以使用synchronized关键字,而这个关键字可以通过两种方法使用
一种是同步代码块:
public void run() {
for(int x = 0;x < 20; x ++) {
synchronized(this) {
if(this.ticket > 0) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + “-------” + “买票:” + this.ticket --);
}
}
}
}
另一种是同步方法:
public synchronized void sale() {//同步方法
if(this.ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + “-------” + “买票:” + this.ticket --);
}
}
死锁
线程如果同步过多就有可能造成死锁
第四十四章 日期操作类
日期处理类
几个重要方法:
无参构造:public Date();
有参构造:public Date(long date);
转换为long型:public long getTime();
Long cur = System.currentTimeMillis();//取得当前时间以long返回
Date date = new Date();
System.out.println(cur);
System.out.println(date);
日期格式化:SimpleDateFormat
构造方法:public SimpleDateFormat(String pattern):需要传递转换格式
将Date转化为String: public final String format(Date date)
将String转化为Date: public Date parse(String source)
throws ParseException
常见的转换单位:年(yyyy)、月(MM)、日(dd)、时(HH)、分(mm)、秒(ss)、毫秒(SS)