正则
常见对象(正则表达式的概述和简单使用)
- A:正则表达式
- 是指一个用来描述或者匹配一系列符合某个语法规则的字符串的单个字符串。其实就是一种规则。有自己特殊的应用。
- 作用:比如注册邮箱,邮箱有用户名和密码,一般会对其限制长度,这个限制长度的事情就是正则表达式做的
- B:案例演示
-
需求:校验qq号码.
- 1:要求必须是5-15位数字
- 2:0不能开头
- 3:必须都是数字
-
a:非正则表达式实现
-
b:正则表达式实现
String regex = “[1 - 9]\d{4,14}”;
System.out.println(“111123”.matches(regex));
-
常见对象(字符类演示)
- A:字符类
- [abc] a、b 或 c(简单类):
"[]"代表【单个】字符//"10"代表"1"和"0"两个字符 - [^abc] 任何字符,除了 a、b 或 c(否定)
- [a-zA-Z] a到 z 或 A到 Z,两头的字母包括在内(范围)
- [0-9] 0到9的字符都包括
- [abc] a、b 或 c(简单类):
常见对象(预定义字符类演示)
- A:预定义字符类
- . 任何字符。"\."代表英文句号
- \d 数字:[0-9]
- \w 单词字符:[a-zA-Z_0-9]
常见对象(数量词)
- A:Greedy 数量词
- X? X,一次或一次也没有
- X* X,零次或多次
- X+ X,一次或多次
- X{n} X,恰好 n 次
- X{n,} X,至少 n 次
- X{n,m} X,至少 n 次,但是不超过 m 次
常见对象(正则表达式的分割功能)
- A:正则表达式的分割功能
- String类的功能:public String[] split(String regex)
- B:案例演示
- 正则表达式的分割功能
常见对象(把给定字符串中的数字排序)
- A:案例演示
- 需求:我有如下一个字符串:”91 27 46 38 50”,请写代码实现最终输出结果是:”27 38 46 50 91”
常见对象(正则表达式的替换功能)
- A:正则表达式的替换功能
- String类的功能:public String replaceAll(String regex,String replacement)
- B:案例演示
- 正则表达式的替换功能
常见对象(正则表达式的分组功能)
- A:正则表达式的分组功能
- 捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B©)) 中,存在四个这样的组:
-
1 ((A)(B(C))) 2 (A 3 (B(C)) 4 (C) // "\\1"代表着第一组又出现了一次 组零始终代表整个表达式。
- B:案例演示
a:切割
需求:请按照叠词切割: “sdqqfgkkkhjppppkl”;
b:替换
需求:我我…我…我.要…要要…要学…学学…学.编…编编.编.程.程.程…程
将字符串还原成:“我要学编程”。
("(.)\1+", “$1”)//$1代表第一组内容
常见对象(Pattern和Matcher的概述)
- A:Pattern和Matcher的概述
- B:模式和匹配器的典型调用顺序
-
通过JDK提供的API,查看Pattern类的说明
-
典型的调用顺序是
-
Pattern p = Pattern.compile(“a*b”);
-
Matcher m = p.matcher(“aaaaab”);
-
boolean b = m.matches();
-
常见对象(正则表达式的获取功能)
- A:正则表达式的获取功能
- Pattern和Matcher的结合使用
- B:案例演示
- 需求:把一个字符串中的手机号码获取出来
常见对象(Math类概述和方法使用)
- A:Math类概述
- Math 类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。
- B:成员方法
- public static int abs(int a)
- public static double ceil(double a)
- public static double floor(double a)
- public static int max(int a,int b) min自学
- public static double pow(double a,double b)
- public static double random()
- public static int round(float a) 参数为double的自学
- public static double sqrt(double a)
常见对象(Random类的概述和方法使用)
- A:Random类的概述
- 此类用于产生随机数如果用相同的种子创建两个 Random 实例,
- 则对每个实例进行相同的方法调用序列,它们将生成并返回相同的数字序列。
- B:构造方法
- public Random()
- public Random(long seed)
- C:成员方法
- public int nextInt()
- public int nextInt(int n)(重点掌握)
常见对象(System类的概述和方法使用)
- A:System类的概述
- System 类包含一些有用的类字段和方法。它不能被实例化。
- B:成员方法
- public static void gc()
- public static void exit(int status)
- public static long currentTimeMillis()
- pubiic static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
- C:案例演示
- System类的成员方法使用
常见对象(BigInteger类的概述和方法使用)
- A:BigInteger的概述
- 可以让超过Integer范围内的数据进行运算
- B:构造方法
- public BigInteger(String val)
- C:成员方法
- public BigInteger add(BigInteger val)
- public BigInteger subtract(BigInteger val)
- public BigInteger multiply(BigInteger val)
- public BigInteger divide(BigInteger val)
- public BigInteger[] divideAndRemainder(BigInteger val)
常见对象(BigDecimal类的概述和方法使用)
- A:BigDecimal的概述
-
由于在运算的时候,float类型和double很容易丢失精度,演示案例。
-
所以,为了能精确的表示、计算浮点数,Java提供了BigDecimal,通过构造传入字符串的形式,开发时推荐
-
用valueOf方法也可以精确表示
-
不可变的、任意精度的有符号十进制数。
-
- B:构造方法
- public BigDecimal(String val)
- C:成员方法
- public BigDecimal add(BigDecimal augend)
- public BigDecimal subtract(BigDecimal subtrahend)
- public BigDecimal multiply(BigDecimal multiplicand)
- public BigDecimal divide(BigDecimal divisor)
- D:案例演示
- BigDecimal类的构造方法和成员方法使用
常见对象(Date类的概述和方法使用)(掌握)
- A:Date类的概述
- 类 Date 表示特定的瞬间,精确到毫秒。
- B:构造方法
- public Date()//代表本地时间
- public Date(long date)//参数为0,则是1970年1月1日
- C:成员方法
-
public long getTime()//通过时间对象获得毫秒值
-
public long currentTimeMillis();//通过系统类(System)的方法获得当前的毫秒值
-
public void setTime(long time)//设置毫秒值,改变时间对象
-
常见对象(SimpleDateFormat类实现日期和字符串的相互转换)(掌握)
- A:DateFormat类的概述
- DateFormat 是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并解析日期或时间。是抽象类,所以使用其子类SimpleDateFormat
- B:SimpleDateFormat构造方法
-
public SimpleDateFormat()//若不指定,便有默认的格式
y:年,M:月,d:日,H:小时,m:分钟,s:秒钟 -
public SimpleDateFormat(String pattern)//创建时间格式化对象,字符串就是指定的格式
y:年,M:月,d:日,H:小时,m:分钟,s:秒钟
-
- C:成员方法
- public final String format(Date date)//传入一个时间对象,把它转换为一个字符串
按照SimpleDateFormat的格式进行匹配,然后输出 - public Date parse(String source)//将字符串转换成为一个Date对象
会抛出一个异常,因为字符串里可能会瞎写
- public final String format(Date date)//传入一个时间对象,把它转换为一个字符串
常见对象(你来到这个世界多少天案例)(掌握)
- A:案例演示
- 需求:算一下你来到这个世界多少天?
常见对象(Calendar类的概述和获取日期的方法)(掌握)
- A:Calendar类的概述
- Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。
//使用方法
Calendar c = Calendar.getInstance();//父类引用子类对象(父类变量,子类对象)
- Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。
- B:成员方法
- public static Calendar getInstance()
- public int get(int field)//传入字段名,详细见API,字段需要输入类名,若静态导入,便不再需要了
月份获取时,因为月是从零开始编号的,所以会比实际时间少一个月
获取天数时,有月中天和周中天,在周中,星期天是第一天,星期六是最后一天
常见对象(Calendar类的add()和set()方法)(掌握)
- A:成员方法
- public void add(int field,int amount)//对指定的字段,进行增减操作
- public final void set(int year,int month,int date)//修改指定的字段,字段名可有多个
- B:案例演示
- Calendar类的成员方法使用
常见对象(如何获取任意年份是平年还是闰年)(掌握)
- A:案例演示
- 需求:键盘录入任意一个年份,判断该年是闰年还是平年
final关键字
final最终的,不可改变的。
1.final可以用来修饰一个类:
A.public final class 类名称 {//...}
含义:不能有任何子类,但有父类(太监类);
如果一个类是final的,那么其中所有的成员方法都不可以进行覆盖重写;
2.final可以用来修饰一个方法;
A.修饰符 final 返回值类型 方法名称(){//...}
含义:此方法为最终方法,不能进行覆盖重写;
对于类,方法来说,abstract关键字不能和final关键字不能同时使用,因为矛盾!
3.final可以用来修饰一个局部变量;
A.“一次赋值,终身使用!”
B.对于基本类型来说,不可变说的是变量中的数据不可改变;
C.对于引用类型来说,不可变说的是变量中的地址值不可改变,内容 可以改变;
4.final可以用来修饰一个成员变量;
A.因为成员变量有默认值,所以有了final之后必须手动赋值,不能再给默认值了;
B.对于final的成员变量;要么直接赋值,要么通过构造方法赋值;二者选其一!
C.使用构造方法赋值时,必须把setXxx给去掉,并让所有重载的构造方法,都会对final的成员变量进行赋值!
内部类
如果一个事物内部包含另一个事物,那么就是一个类内部包含另一个类;
分类:
成员内部类
-
成员内部类的定义格式:
修饰符 class 外部类名称 { 修饰符 class 内部类名称{//...} }//注意:内用外,随意访问;外用内,需要内部类对象;
-
内部类的使用:两种方法
间接方式:在外部的方法当中,使用内部类;然后main方法只是调用外部类的方法;
直接方式:公式:
【外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();】
-
内部类的同名变量访问
在内部类访问外部类:外部类名称.this.变量名
局部内部类
-
如果一个类是定义在一个方法内部的,那么就是一个局部内部类。“局部”:只有当前方法所属的方法才能使用它,出了这个方法外面就不能用了。
-
定义格式:
修饰符 class 外部类名称{ 修饰符 返回值类型 外部类方法名称(参数列表) { class 局部内部类名称{//...} } }
3)注意事项:
局部内部类,如果希望访问所在方法的局部变量,那么这个局部遍历必须是有效final的
。
备注:从Java8开始,如果局部变量事实上不变,那么final关键字就可以省略不写。
原因:
1.new出来的内部类对象是放在堆内存里的。
2.局部变量是跟着方法走的,在栈内存当中。
3.方法运行结束后,立即出栈,局部变量会立即消失。
4.但是new出来的对象会在堆当中持续存在,直至被垃圾回收消失。
匿名内部类(局部内部类的一种)
-
如果接口的实现类(或者是父类的子类)只需要使用唯一的一次。
那么这种情况就可以省略掉该类的定义,而改为使【匿名内部类】。 -
匿名内部类的定义格式:
接口名称 对象名 = new 接口名称() { //覆盖重写所有方法 };//分号不能忘记写
-
格式解析(对“new 接口名称() {…}”进行解析):
A.new代表的是创建对象的动作;
B.接口名称就是匿名内部类需要实现哪个接口
C.{…}这才是匿名内部类的内容 -
注意事项:
A.匿名内部类,在【创建对象】的时候,只能使用一次。 如果希望使用多次创建对象,而且类的内容一样的话,那么就必须使用单独定义的实现类了。 B.若把等号左边的接口对象给删掉,那么便成为一个匿名对象。 而匿名对象只能调用唯一的一次方法,若想多次使用方法,那么便必须给它取个名字; C.匿名内部类是省略了【实现类/子类名称】,但是匿名对象省略了【对象名称】; 强调:匿名内部类和匿名对象不是一回事!!!
- 类作为一个成员变量类型
用类作为成员变量时,在主类里就是普通的定义变量(参考字符串),使用时必须先创建一个类对象,然后将这个对象作为参数传入这个类所在的主类里! - 接口作为一个成员变量类型
- 用接口作为成员变量时,在主类里就是普通的定义变量(参考字符串),使用时必须先创建一个实现类,然后将这个实现类创建的对象作为参数传入这个接口所在的主类里!
- 可以使用匿名内部类;
- 还可以使用匿名内部类和匿名对象相结合;
抽象类和抽象方法
抽想的概念:
A.仅仅定义一个名字方法,并未有具体的方法执行!
抽象类:
A.定义:public abstract class 名字{}
B.创建:不能直接用new创建抽象类对象,必须要用一个子类来继承抽象方法。
C.子类必须覆盖重写抽象父类当中所有的抽象方法。覆盖重写(实现):子类去掉抽象方法里的abstract关键字,然后补上方法体大括号;
D.创建子类对象来使用
抽象方法:
public abstract void 方法名();
抽象方法必须在抽象类!
注意事项
关于抽象类的使用,以下为语法上要注意的细节,虽然条目较多,但若理解了抽象的本质,无需死记硬背。
1. 抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。
理解: 假设创建了抽象类的对象,调用抽象的方法,而抽象方法没有具体的方法体,没有意义。
2. 抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的。I理解: 子类的构造方法中,有默认的super(),需要访问父类构造方法。
3. 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。理解:未包含抽象方法的抽象类,目的就是不想让调用者创建该类对象,通常用于某些特殊的类结构设计。
4. 抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象类。理解:假设不重写所有抽象方法,则类中可能包含抽象方法。那么创建对象后,调用抽象的方法,没有意义。
继承
继承的特点
继承解决的主要是共性抽取!父类,基类,超类:子类,派生类。
继承关系的特点:
A.子类可以拥有父类中可继承的“内容”!
B.子类还可以拥有自己的内容!
C.“子类就是一个父类”,也就是说子类可以当作一个父类看待,关系:is-a;
格式:
A.定义父类时就是定义一个普通的类!
B.定义子类时,需要写
public class 子类名称 extends 父类名称 {//}
成员变量的访问规则:
在父子类的继承关系当中,如果成员变量名重名,则创建子类对象时,访问有两种方式:
A.直接调用:创建子类对象来调用成员变量,等号左边是谁就优先调用谁,没有则向上找
B.间接调用:间接通过调用成员方法访问成员变量,该方法属于谁,就优先用谁,没有则往上找
成员方法的访问规则:
5.1在父子类的继承关系当中,如果成员方法名重名,则创建子类对象时,访问方法时有两种方式:
A.创建的是谁就优先用谁!没有就向上找!
【注意】
A.无论是访问成员变量还是成员方法,没有时只会往上找,不会向下找
继承中成员方法的覆盖重写(覆盖,覆写):
A.概念:重写(Override),在继承关系当中,方法的名称一样,参数列表也一样。
B.重写(Override)和重载(Overload)的区别
a.重写的方法名称一样,参数列表【也一样】,重载的方法名称一样,参数列表【不一样】;
C.创建的是子类对象,则优先用子类对象方法!
D.【注意事项】:
a.必读保证父子类的方法名称和参数列表都一样;注释检测:@Override;注释不写也没事!只是检测用的!
b.子类方法的返回值必须小于等于父类的返回值的范围,Object类是所有类的公共最高父类(祖宗类),java.lang.Strig是其子类之一!
c.子类方法的权限必须【大于等于】父类方法的权限修饰符。小扩展:public > protected > (defult) > private 备注:(defult)不是关键字,而是什么都不写,留空!
成员方法覆写的应用:
A.对于已经投入使用的类,尽量不要进行修改。推荐定义一个新的类,来重复利用其中共性内容,并且添加改动新内容。
B.在原有的功能上进行添加新功能,即继承父类的子类需要添加新东西,要想使用父类里的被覆盖的类,需要使用【super】关键字:方法名.super();
继承关系当中构造方法的访问特点:
A.子类构造方法当中有一个默认隐含的“super()”调用【无参数】的构造方法,【所以一定先调用的父类构造方法,后执行的子类构造,没有便赠送!】
B.子类可以通过super来调用父类里的重载方法!
C.super的父类构造调用,必须是子类构造方法的【第一个】语句!
Java里的继承三个特点:
A.Java语言是单继承的。一个类的直接父类只能有一个!
B.Java语言可以多级继承。class A{}; class B extends A{};class C extends B{};A是B的父类,B是C的父类,A是C的父类!Object(java.lang.Object)上面就没有了父类;
c.Java语言父类下的子类并不唯一!
PS:你只能有一个老子,但你老子不一定只有你一个儿子!
super关键字的三种用法:
A.在子类的成员方法中,访问父类的成员变量;super.变量名;
B.在子类的成员方法中,访问父类的成员方法;super.方法名();
C.在子类的构造方法中,访问父类的构造方法;super.方法名();
this关键字的三种用法:
super关键字用于访问父类,this用于访问子类
A.在本类的成员方法中,访问本类的成员变量。
B.在本类的成员方法中,访问本类的成员方法。起到一个强调字面作用
C.在本类的构造方法中,访问本类的构造方法。
D.在C中方法中,this(...);调用只能放在构造方法的第一位,也是唯一一位;且super和this两种构造调用,不能同时使用!
接口
接口的基本定义格式 :
public interface 接口名称 {};
接口当中可以包含的组成部分有:
1.抽象方法【重点】
2.常量
3.默认方法(Java8)
4.静态方法(Java8)
5.私有方法(Java9)
如何定义一个抽象方法:
1.接口里的抽象方法,修饰符如果写必须写public abstract
2.接口里的抽象方法,修饰符可以不写,默认就是 public abstract
3.抽象方法只有方法头,不能有具体方法大括号
4.如果要想使用定义好的接口,必须有一个接口的“实现类”
定义实现类的格式:
public class 实现类名称 implements 接口名称{
//一定要覆盖重写所有的抽象方法
}
什么是覆盖重写(Override)抽象方法?
1.将接口当中的抽象方法抄写过来
2.去掉abstract关键字
3.写上大括号方法体
Cat就是Animal接口的实现类,Cat类实现了Animal接口。
如何使用接口和实现类?
- 创建
接口名称 引用名 = new 实现名称(); - 调用
引用名.抽象方法名(参数); - 注意
- 左边是接口类型,那么只能调用接口当中定义好的内容,不能调用右侧实现类的当中特有的内容。(接口隔离)
- 当调用接口当中的抽象方法时,真正运行的是右侧new的时候类的具体方法内容。
- 总结就是一句话:调用的时候看左边,运行的时候看右边。
- 使用接口作为左侧类型的好处所在:
- 屏蔽了右侧的个性特有的内容,达到隔离、统一的目的。
- 将接口作为参数传入方法后,就不用区别一些对象;
面向接口编程:
如果使用的功能,接口已经可以实现,那么就不在乎具体的类是谁,只在乎接口即可;
函数式编程Lambda表达式
@FunctionalInterface
检验是否为函数式接口,只要有且仅有一个抽象方法的接口,就是函数表达式!
函数表达式接口的好处: 不用写实现类
在Lambda表达式当中,凡是可以推导的,都可以省略的。
-
Lambda表达式当中的参数类型可以省略不写。
-
如果参数有且仅有一个,那么小括号也可以省略。
-
如果只有一个,那么大括号和return也可以省略。
Lambda表达式:(a, b) -> a + b; method方法需要一个(Calculator)接口类型的参数 Lambda表达式就是充当了一个Calculator接口类型的参数
初步了解:
- Lambda表达式前面的小括号,其实就是接口抽象方法的小括号。
- 箭头代表拿着小括号里的数据做什么事情,是一个指向动作
- 箭头后面就代表拿到了参数之后做什么事情
lambda表达式的语义本身就代表了怎么做这件事,没有对象的概念在里面。
Java当中使用Lambda表达式的前提是:必须有“函数式接口”。
概念:有且仅有一个抽象方法的接口,叫做函数式接口。
检验是否为函数式接口?
在public interface 函数式接口名字 {};上面写
@FunctionalInterface
Lambda表达式要想使用,一定要有函数式接口的推断环境。
- 要么通过方法的参数类型来确定哪个函数式接口
- 要么通过赋值操作来确定是哪个函数式接口
Lambda的格式就是为了将抽象方法,翻译成以下三点:
- 一些参数(方法参数)
- 一个箭头
- 一些代码(方法体,大括号)
例如抽象方法:
public abstract int sum(int a, int b);
翻译成为Lambda表达式的标准格式:
(int a, int b) -> { return a + b; }
异常
异常(异常的概述和分类)
- A:异常的概述
- 异常就是Java程序在运行过程中出现的错误。
- B:异常的分类
- 通过API查看Throwable
- Error
- 服务器宕机,数据库崩溃等
- Exception
C:异常的继承体系 - Throwable
- Error
- Exception
- RuntimeException
异常(JVM默认是如何处理异常的)
- A:JVM默认是如何处理异常的
- main函数收到这个问题时,有两种处理方式:
- a:自己将该问题处理,然后继续运行
- b:自己没有针对的处理方式,只有交给调用main的jvm来处理
- jvm有一个默认的异常处理机制,就将该异常进行处理.
- 并将该异常的名称,异常的信息.异常出现的位置打印在了控制台上,同时将程序停止运行
- B:案例演示
- JVM默认如何处理异常
(try…catch的方式处理异常1)
- A:异常处理的两种方式
- a:try…catch…finally
- try catch
- try catch finally
- try finally
- b:throws
- a:try…catch…finally
- B:try…catch处理异常的基本格式
- try…catch…finally
- C:案例演示
- try…catch的方式处理1个异常
异常(try…catch的方式处理异常2)
- A:案例演示
- try…catch的方式处理多个异常
- JDK7以后处理多个异常的方式及注意事项
- JDK7引用了逻辑运算符或(|)
异常(编译期异常和运行期异常的区别)
- A:编译期异常和运行期异常的区别
-
Java中的异常被分为两大类:编译时异常和运行时异常。
-
所有的RuntimeException类及其子类的实例被称为运行时异常,其他的异常就是编译时异常
-
编译时异常
- Java程序必须显示处理,否则程序就会发生错误,无法通过编译
-
运行时异常
- 无需显示处理,也可以和编译时异常一样处理
-
- B:案例演示
- 编译期异常和运行期异常的区别
异常(Throwable的几个常见方法)
- A:Throwable的几个常见方法
- a:getMessage()
- 获取异常信息,返回字符串。
- b:toString()
- 获取异常类名和异常信息,返回字符串。
- c:printStackTrace()
- 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
- a:getMessage()
- B:案例演示
- Throwable的几个常见方法的基本使用
异常(throws的方式处理异常)
- A:throws的方式处理异常
- 定义功能方法时,需要把出现的问题暴露出来让调用者去处理。
- 那么就通过throws在方法上标识。
- B:案例演示
- 举例分别演示编译时异常和运行时异常的抛出
异常(throw的概述以及和throws的区别)
- A:throw的概述
- 在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出。
- B:案例演示
- 分别演示编译时异常对象和运行时异常对象的抛出
- C:throws和throw的区别
- a:throws
- 用在方法声明后面,跟的是异常类名
- 可以跟多个异常类名,用逗号隔开
- 表示抛出异常,由该方法的调用者来处理
- b:throw
- 用在方法体内,跟的是异常对象名
- 只能抛出一个异常对象名
- 表示抛出异常,由方法体内的语句处理
- a:throws
异常(finally关键字的特点及作用)
- A:finally的特点
- 被finally控制的语句体一定会执行,连结束方法语句return也不能阻碍它的执行!
- 特殊情况:在执行到finally之前jvm退出了(比如System.exit(0))
- B:finally的作用
- 用于释放资源,在IO流操作和数据库操作中会见到
- C:案例演示
- finally关键字的特点及作用
异常(finally关键字的面试题)
- A:面试题1
- final,finally和finalize的区别
- B:面试题2
- 如果catch里面有return语句,请问finally的代码还会执行吗?如果会,请问是在return前还是return后。
异常(自定义异常概述和基本使用)
- A:为什么需要自定义异常
- 通过名字区分到底是什么异常,易于找到解决办法!
- 举例:人的年龄
- B:自定义异常概述
- 继承自Exception
- 继承自RuntimeException
- C:案例演示
- 自定义异常的基本使用
异常(异常的注意事项及如何使用异常处理)
- A:异常注意事项
- a:子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。(父亲坏了,儿子不能比父亲更坏)
- b:如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常
- c:如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws
- B:如何使用异常处理
-
原则:如果该功能内部可以将问题处理,用try,如果处理不了,交由调用者处理,这是用throws
-
区别:
- 后续程序需要继续运行就try
- 后续程序不需要继续运行就throws
-
如果JDK没有提供对应的异常,需要自定义异常。
-
IO流
File类(File类的概述和构造方法)
- A:File类的概述
- File更应该叫做一个路径
- 文件路径或者文件夹路径
- 路径分为绝对路径和相对路径
- 绝对路径是一个固定的路径,从盘符开始
- 相对路径相对于某个位置,在eclipse下是指当前项目下,在dos下
- 查看API指的是当前路径
- 文件和目录路径名的抽象表示形式
- “\”是转义字符,若变换为盘符路径,需要加“\”或“/”;exitsts是是否存在的返回值为布尔值的方法
- File更应该叫做一个路径
- B:构造方法
- File(String pathname):根据一个路径得到File对象
- File(String parent, String child):根据一个目录和一个子文件/目录得到File对象
- File(File parent, String child):根据一个父File对象和一个子文件/目录得到File对象
- C:案例演示
- File类的构造方法
File类(File类的创建功能)
- A:创建功能
- public boolean createNewFile():创建文件 如果存在这样的文件,就不创建了,即使不加后缀名,也会创建出来;
- public boolean mkdir():创建文件夹 如果存在这样的文件夹,就不创建了,文件夹也可以有后缀。
- public boolean mkdirs():创建文件夹,如果父文件夹不存在,会帮你创建出来。//创建多级目录!
- 以上三个方法返回值都是布尔类型!
- B:案例演示
-
File类的创建功能
-
注意事项:
- 如果你创建文件或者文件夹忘了写盘符路径,那么,默认在项目路径下。
-
File类(File类的重命名和删除功能)
- A:重命名和删除功能
- public boolean renameTo(File dest):把文件重命名为指定的文件路径
- public boolean delete():删除文件或者文件夹
- B:重命名注意事项
- 如果路径名相同,就是改名。
- 如果路径名不同,就是改名并剪切。
- C:删除注意事项:
- Java中的删除不走回收站。
- 要删除一个文件夹,请注意该文件夹内不能包含文件或者文件夹
File类(File类的判断功能)
- A:判断功能
- public boolean isDirectory():判断是否是目录
- public boolean isFile():判断是否是文件
- public boolean exists():判断是否存在
- public boolean canRead():判断是否可读
- public boolean canWrite():判断是否可写
- public boolean isHidden():判断是否隐藏
- public boolean setReadable(boolean):如何设置可读//windows系统认为所有的文件都是可读的
- public boolean setWritable(boolean): 如何设置可写,windows系统可以改为不可写
- B:案例演示
- File类的判断功能
File类(File类的获取功能)
- A:获取功能
- public String getAbsolutePath():获取绝对路径
- public String getPath():获取路径,获取的是构造方法里传入的路径
- public String getName():获取名称
- public long length():获取长度。字节数
- public long lastModified():获取最后一次的修改时间,毫秒值
- public String[] list():获取指定目录下的所有文件或者文件夹的名称数组
- public File[] listFiles():获取指定目录下的所有文件或者文件夹的File数组
- 但凡打印对象时,打印出来的不是类名加哈希值,那么就是在其内部对Object的toString方法进行了重写!
- B:案例演示
- File类的获取功能
File类(输出指定目录下指定后缀的文件名)
- A:案例演示
- 需求:判断E盘目录下是否有后缀名为.jpg的文件,如果有,就输出该文件名称,
- 1.先创建一个父路径的File对象,然后用list方法得到名字的数组,遍历数组即可。endsWith,字符串里判断后缀名的方法
- 2.创建一个父路径的File对象,然后用list方法得到File对象的数组,遍历数组即可。此方法比第一个要好,因为可以判断是文件夹还是文件,若是文件夹,便可以用递归继续扫描文件夹里的文件。
File类(文件名称过滤器的概述及使用)
- A:文件名称过滤器的概述
- public String[] list(FilenameFilter filter)
- public File[] listFiles(FileFilter filter)
- B:文件名称过滤器的使用
- 需求:判断E盘目录下是否有后缀名为.jpg的文件,如果有,就输出该文件名称
- C:源码分析
- 带文件名称过滤器的list()方法的源码
- D:注意事项
- FilenameFilter文件名称过滤器,是一个接口,里面只有一个accept方法,可以使用匿名内部类,来简化代码;在accept里面添加一个判断语句,使得符合条件的文件,存入数组!
- toArray,集合转为数组的方法
FileWriter
可以将数据写入纯文本当中,没有便创建,一般是覆盖写入,有五个构造方法,
-
导包
import java.io.FileWriter;
CTRL+SHIFT+O 便捷键导入; -
创建,构造方法
public FileWriter(String filename),参数字符串就是文件的路径名称
FileWriter fw = new FileWriter(“file01.txt”);
文件扩展名只能决定用什么软件打开文件(打开方式),不能决定其内容
总结一下:FileWriter基本使用步骤:创,写,关。
关闭的写法是fw.close();
【追加写入】
一般FileWrite写入是覆盖写入,若想使用追加写入,便使用下面方法
public FileWriter(String filename, boolean append);若布尔值是true,便追加写入
【换行写入】
换行也是一种字符,叫换行符:
windows当中的换行符是 "\r\n" 这叫做两个字符"\r"和"\n"
macOS当中的换行符是早期是"\r",现在是"\n"
liunx当中的换行符是 "\n"
【文字与数字的转换】
-
所有的数据都是数字,文本的规则是ASCII码和Unicode表;48是0;65是A;97是A;
-
【FileWrite方法的重载】
A.public void write(int ch);参数是单个文字对应的数字(参考ASCII码和Unicode表);
B.public void write(String str);写一个完整的字符串;
C.public void write(String str, int offset, int count);写字符串的一部分内容;
D.public void write(char[] array)写一个完整的字符数组;
E.public void write(char[] array, int offset, int count);写字符数组中的一部分;
F.注释:offset是想要字符的开始索引,count是想要几个字符; -
BufferedWriter是FileWriter的升级版,两者差不多,也是一种用来写文件的类,属于字符输出!
最大区别BufferedWriter肚子里有一个8192个char[]字符数组,当中缓冲区使用;
每次在写数据的时候,实际上都是在不断地向缓存数组当中添加字符。
如果缓冲数组满了那么将会统一的写到硬盘的文件当中;
如果还未写满,那么就等待下一次写入;
如果最终关闭时,数组仍然未满,那么也会将剩余的有效部分写到硬盘文件。 -
如何使用BufferedWriter?
A.首先创建一个普通的FileWriter;
B.将这个普通的FileWriter包装成为缓冲的BufferedWriter,用构造方法就行;
C.后面BufferedWriter使用方法heFileWriter方法差不多;
D.构造方法:public BufferedWriter(FileWriter fw);参数就是一个普通的FileWriter对象; -
BufferedWriter与File的方法区别
A.BufferedWriter额外提供了一个换行的方法;
B.public void newLine(); 将会自动根据系统来打换行符;以便兼容所有系统;
C.调用方法:bw.newLine();不需要参数; -
【注意事项】
- 本方法会有异常抛出,可能是因为系统权限不足,内存不足…现阶段不处理异常,在mian方法参数后面加入throws IOException,表示不处理异常;
- 千万不能忘记最后调用close方法;
- FileWriter是类。write是方法;
- 使用BUfferedWriter时,要记得关闭流时关闭的是BufferedWriter的流;
FileReader
用来将文本文件里的字符读取到程序当中。
使用的步骤:
- 导包
import java.io.FileReader; - 创建,构造方法
public FileReader(String filename);参数仍是文件的路径名。
FileReader fr = new fileReader(“filename.txt”);
如果指定的文件名对应的文件不存在,那么会报错。 - 使用,成员方法
读取单个字符,public int read();读取下一个字符,得到对应的ASCII码或Unicode值。
返回值是一个int值,是ASCII码或Unicode表;
关闭释放资源:public void close();
使用FileReader的步骤也是三个字:创,建,关。
-
为了提高速率,FileReader提供了另外一种重载形式的read方法;
public int read(char[] buf);一次读取整个字符串的数据。
参数是一个字符数组,用来承载读取到的多个字符。
【返回值代表的是数组当中的读取的有效个数。】 -
BufferedWriter和FileWriter差不多,也是用来读取文件的一种字符输入流。
区别就在于BufferedReader肚子里有一个8192长度的char[]字符数组,当做缓冲区使用。
当读取数据的时候,一次性从硬盘当中读取最多8192个字符,放在数组缓冲区当中。
在调用read方法的时候,只是从缓冲区当中拿出来字符进行使用。
如果缓冲区当中的字符被“取空”,那么将会自动再次读取最多8192个再次放在缓神区当中。 -
如何使用BufferedReader?
A.首先创建一个普通的FileReader
B.将这个普通的FileReader包装成为缓沖的BufferedReader,构造方法。
C.使用起来和普通的FileReader基本没有区别.
D.构造方法:public BufferedReader(FileReader fr);参数就是一个普通的FileReader对象。 -
BufferedReader额外提供了一个方法,可以读取一整行字符串。
public String readLine();读取一整行字符串,返回值当中不包含换行符。
【注意事项】
- 每次调用read();都会读取下一位字符;
- 在print输入中也可以进行强-制转换;
- FileReader是类。read是方法;
- FileReader里的read方法执行到最后是,会返回-1,代表没有更多内容;
- BufferedReader里的read方法执行到最后是,会返回null,代表没有更多内容;