1.面向对象编程,多态调用
javabean类 用来描述一类事物的类。
测试类 用来检查其他类是否书写正确。
工具类 不是用来描述一类事物的,而是帮我们做一些事情的类。
工具类要求:1.类名见名知意,2.私有化构造方法,3.方法定义为静态。
静态方法中只能访问静态、非静态方法可以访问所有、静态方法中没有this关键字。
封装:对象代表什么,就得封装对应的数据,并提供数据对应的行为。
子类只能访问父类中非私有的成员。
子类不能继承父类的构造方法、子类可以继承父类的成员变量,但父类中私有的成员变量,子类不能直接使用,需要用get/set方法、子类可以继承父类中的虚方法,只有虚方法表中的方法才能使用。
Object的虚方法表中有五个方法。
继承中成员变量的访问特点:就近原则。局部位置——本类成员位置——父类成员位置
方法重写的本质是,在子类的虚方法表中,子类的方法覆盖了父类的同名方法。
重写的方法尽量与父类保持一致,重写方法的名称,形参列表必须一致,访问权限子类必须大于等于父类,返回值类型子类必须小于等于父类。
继承中构造方法的访问特点:子类中所有的构造方法默认先访问父类中的无参构造,再执行自己。
子类构造方法的第一行语句默认都是:super(),不写也存在,且必须在第一行。
若要调用父类有参构造,必须手动写super进行调用。
多态调用成员的特点:
调用成员变量:编译看左边,运行也看左边
编译看左边:javac编译代码的时候,会看左边的父类中有没有这个变量,如果有,编译成功,如果没有,编译失败。
运行也看左边:java运行 代码的时候,实际获取的就是左边父类中成员变量的值。
调用成员方法:编译看左边,运行看右边
编译看左边:javac编译代码的时候,会看左边的父类中有没有这个变量,如果有,编译成功,如果没有,编译失败。
运行也看左边:java运行 代码的时候,实际上运行的时子类中的方法。
多态的弊端:不能调用子类中的特有方法
原因:调用成员方法:编译看左边,运行看右边。在编译的时候会先检查左边的父类中有没有这个方法,如果没有,直接报错。
解决方法:变回子类类型
例:Animal a = new Dog();——Dog b = (Dog) a ;再用调用方法。
2.异常
异常:异常就是代表程序出现的问题。
异常(Exception)和错误(Error)都是java.lang.Throwable的子类
错误分为三类:语法错误,运行错误,逻辑错误。
异常体系的最上层父类是Exception
异常分为两类:编译时异常(在编译阶段,必须要手动处理,否则代码报错)、运行时异常(在编译阶段是不需要处理的,是代码运行时出现的异常),区别是提示阶段不同
运行时异常:RuntimeException本身和所有子类。核心:就表示由于参数错误而导致的问题
编译时异常:除了RuntimeException本身和它的所有子类,其他的异常都是编译时异常。核心 :提醒程序员检查本地信息
异常的作用:异常是用来查询bug的关键参考信息、异常可以作为方法内部的一种特殊返回值,以便通知调用者底层的执行情况。
异常的处理方式:JVM默认的处理方式、自己处理(捕获异常)、抛出异常。
JVM默认的处理方式:把异常的名称、异常原因及异常出现的位置等信息输出在了控制台;程序停止执行,下面的代码不会再执行了
自己处理(捕获异常)目的:当代码出现异常时,可以让程序继续往下执行。try~catch体系
只有当try中出现了异常才会执行catch里面的代码
如果在try中遇到了多个问题,会写多个catch与之对应。细节:如果我们要捕获的多个异常中存在父子关系,父类要写在下面。
如果try中遇到的问题没有被捕获,就会执行JVM默认的处理方式。
如果try中遇到了问题,问题下面的代码就不会再执行了,会直接跳转到对应的catch当中,执行catch里面的语句体,如果没有对应的catch与之匹配,就会执行JVM默认的处理方式。
getMessage返回此throwable的详细消息字符串、toString返回此可抛出的简短描述、printStackTrace把异常的错误信息输出在控制台,但仅仅是打印信息,不会停止程序运行,底层是利用System.err.println进行输出,把异常的错误信息以红色字体输出在控制台。
抛出异常:
throws:写在方法定义处,表示声明一个异常,告诉调用者,使用本方法可能会有那些异常
编译时异常:必须要写。
运行时异常:可以不写。
2. throw:写在方法内,结束方法,手动抛出异常对象,交给调用者,方法中下面的代码不再执行了。
idea总包裹语句快捷键:ctrl + alt + t。
idea查看源码快捷键:ctrl + n.
idea追跟上一级快捷键:ctrl + b。
自定义异常:
意义:为了让控制台的报错信息更加见名知意。
定义异常类,名字技巧:问题+Exception
写继承关系,继承时,如果是运行时异常,继承RuntimeException ; 如果是编译时异常,直接继承Exception。
空参构造
带参构造
如果是编译时异常,一定要在方法处声明。
File类
File:路径
利用File可以获取文件信息(大小,文件名,修改时间)、判断文件的类型、创建文件/文件夹、删除文件/文件夹。
File对象表示一个路径,可以是文件的路径,也可以是文件夹的路径,这个路径可以是存在的,也可以是不存在的。
绝对路径与相对路径的区别:绝对路径带盘符。
File类中的length方法用于返回文件的大小(字节数量),细节1:这个方法只能获取文件的大小,单位是字节,若单位是M、G,可以不断的除以1024,细节2:这个方法无法获取文件夹的大小,如果要获取一个文件夹的大小,需要把这个文件夹里面所有的文件大小都累加起来。
File类中的getName方法细节:如果方法的调用者是文件,会返回文件名+后缀名;如果方法的调用者是文件夹,会返回文件夹的名字。
File类中的lastModified方法的返回值是文件的最后修改时间(单位:毫秒值)。
File类中的delete方法默认只能删除文件和空文件夹,delete方法直接删除不走回收站。
File类中的createNewFile方法创建一个新的空的文件。细节:如果当前路径表示的文件是不存在的,则创建成功,方法返回true;如果当前路径表示的文件是存在的,则创建失败,方法返回false、如果父级路径是不存在的,那么方法会有异常IOException、createNewFile方法创建的一定是文件,如果路径中不包含后缀名,则创建一个没有后缀的文件。
File类中的mkdir方法只能创建单级文件夹,无法创建多级文件夹。
File类中的mkdirs方法,既可以创建单级文件夹,又可以创建多级文件夹。
IO流
IO流:传输方式
什么是IO流?IO流:存储和读取数据的解决方案;I:input;O:output;流:像水流一样传输数据。
IO流的作用:用于读写数据(本地文件,网络)。
IO流的分类:
按流的方向:输入流(读取):把本地文件中的数据读取到程序中、输出流(写出):把程序中的数据写出到文件中。
按操作文件类型:字节流(可以操作所有类型的文件)可以分为:字节输出流(OutputStream)和字节输入流(InputStream)、字符流(只能操作纯文本文件)可以分为:字符输入流(Reader)和字符输出流(Writer)。
纯文本文件:用Windows系统自带的记事本打开并能读懂的文件,例:txt文件,md文件,xml文件,irc文件等。
idea抛出异常快捷键:alt + 回车。
read方法表示读取数据,而且是读取一个数据就移动一次指针。
字节流一次读取一个字节
字节输出流基本用法
字节输入流基本用法
文件拷贝:
释放资源时与创建对象的顺序相反。
try...catch异常处理:try...catch由三部分组成,try、catch、finally。finally里面的代码一定被执行,除非虚拟机停止。
局部变量只在所属的大括号中是有效的。
字节流读取中文会出现乱码
计算机的存储规则:在计算机中,任意数据都是以二进制的形式来存储的。二进制:由0和1组成,每一个0或1都是一个bit(比特位)。
一字节对应八个比特位,存储2的八次方(256)个数据,字节是计算机中最小的存储单元。存储英文(一个字母)时一个字节就够了
ASCII字符集(编码表):记录了128个数据(十进制0~127)。针对欧美。
ASCII编码规则:前面补0,补齐8位。
ASCII解码规则:直接转成十进制。
GBK字符集:Windows系统默认使用,系统显示:ANSI。针对中国。
GBK英文编码规则:不足8位,前面补0。
GBK汉字编码规则:不用变动
一个汉字用两个字节来存储。前面的第一个字节叫高位字节,后面的一位字节叫低位字节。
高位字节二进制一定以1开头,转成十进制之后值一个负数
Unicode字符集:国际标准字符集(万国码)。
UTF-8不是一个字符集,是Unicode字符集的一种编码方式
乱码出现的原因:
读取数据时未读完整个汉字
编码和解码时的方式不统一
如何避免出现乱码:
不要用字节流读取文本文件,字节流读取中文会乱码,拷贝时不会乱码。
编码解码时使用同一个码表,同一个编码方式
java中编码和解码的方法:
idea默认使用utf-8;eclipse默认使用GBK。
字符流的底层是字节流。字符流= 字节流+字符集。
特点:
输入流:一次读一个字节,遇到中文时,一次读多个字节。
输出流:底层会把数据按照指定的编码方式进行编码,变成字节再写到文件中
使用场景:对纯文本文件进行读写操作。
字符输入流:FileReader
read(chars):读取数据,解码,强转三步合并了把强转之后的字符放到数组当中。有参的read=空参的read+强制类型转换。
字符输出流:FileWriter
打印流是高级流也是用来包装基本流的,打印流不能读只能写,打印流只有输出流
打印流:
分类:打印流一般是指:PrintStream(字节打印流),PrintWriter(字符打印流)两个类
特点:
打印流只操作文件目的地,不操作数据源
特有的写出方法可以实现,数据原样写出
特有的写出方法,可以实现自动刷新,自动换行
特殊的打印流,系统中的标准输出流,是不能关闭,在系统中是唯一的
序列化流(ObjectOutputStream)是高级流也是用来包装基本流的,是字节流的一种,负责输出数据,与之对应的还有一个输入流(反序列化流/ObjectInputStream)。
序列化流/对象操作输出流可以把java中的对象写到本地文件中
Serializable接口里面没有抽象方法,标记型接口,一旦实现了这个接口,就表示实现该接口的类可以被序列化
反序列化流/对象操作输入流:可以把序列化到本地文件中的对象,读取到程序中来。
序列化流/反序列化流细节:
使用序列化流将对象写到文件时,需要让javabean类实现Serializable接口,否则会出现NotSerializableException异常
序列化流写到文件中的数据时不能修改的,一旦修改就无法再次读回来了
序列化对象后,修改了javabean后,再次反序列化,会有问题,会抛出InvalidClassException异常。解决方案:给javabean类添加serializableUID(序列号,版本号)。
如果一个对象中的某个成员变量的值不想被序列化,可以给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程。
Stream流
stream流的作用:结合了lambda表达式,简化集合,数组的操作。
stream流的使用步骤:
先得到一条Stream流(流水线),并把数据放上去
利用Stream流中的API进行各种操作。
中间方法:过滤,转换。方法调用完毕之后,还可以调用其他方法
终结方法:统计,打印。最后一步,调用完毕之后,不能调用其他方法。
Stream接口中静态方法of的细节:
方法的形参是一个可变参数,可以传递一堆的零散数据,也可以传递数组,但是数组必须是引用数据类型的,如果传递基本数据类型,是会把整个数组当做一个元素,方法stream中。
Buffered(缓冲区)
缓冲流:字节缓冲输入流,字节缓冲输出流,字符缓冲输入流,字符缓冲输出流。
高级流:缓冲流,转换流,序列化流,打印流,压缩流,对基本流进行包装。
字节缓冲流:原理:底层自带了长度为8192的缓冲区提高性能
字符缓冲流:原理:底层自带了长度为8192的缓冲区提高性能
BufferedReader的特有构造方法readLine方法在读取的时候,一次读一整行,遇到回车换行结束,但是不会将回车换行读到内存当中。
转换流
解压缩流/压缩流
解压本质:把每一个Zipentry按照层级拷贝到本地另一个文件夹中。
在java当中只能识别后缀名是.zip的压缩包。
解压缩流(ZipInputStream):
压缩本质:把每一个(文件/文件夹)看成ZipEntry对象放在压缩包中。