软件开发工具包(包含jre和软件开发工具)(开发不同,jdk的大小不同,jdk的包也不同:javaee:企业版,javase:个人版,javame:袖珍版)
jvm和核心类库(编写简单java程序)(jar容器)
JAVA跨平台的根本,(java虚拟机)
所以总结:只要安装jdk即可。
固定不变的量 整数,小数,布尔,字符,字符串
在内存中开辟一块空间,可以存储数据,但是一个变量只能存储一个值,这个值是可以改变的。
单行注释://
多行注释:/**/
文档注释:/** */在方法中显示
被java赋予了特殊含义的单词,只能用,不能改,也不能重名
程序中需要我们自己命名的
由26个英语字母,数字,_,$组成
不能和关键字同名
不能以数字开头
区分大小写
规范变量的内存大小,空间(取值)
基本数据类型(数值型,整数型,浮点型,字符型,布尔型)和引用数据类型(数组,类,接口)
有符号数最高为符号位。
float 4个字节(科学计算法,牺牲精度,最大值比long大的多)
double 8个字节(科学计算法,牺牲精度,最大值比long大的多)
long 8个字节 int 4个字节 short 2个字节 byte 1 个字节
ASCII值(国标码)(中文字符码GBK一个汉字对应俩个字节 GB-2312)一个汉字对应三个字节(UTF-8)uncode (内部编码,俩个字节)lso8859-1(欧洲)(不支持中文)
大写A 65(32)
小写a 97
0 48
确定数据类型的优先级,从低到高
char,byte-short-int-long-float-double
1B = 8b 1kB=1024B
1MB=1024kB 1GB=1024MB
1TB=1024GB 1PB=1024TB
System.out.println(14 + 'A' + 12);//字符转换成整数运算
算数运算符:+ - * / % ++ --,赋值运算符 = += -= *= /= %= ^=,逻辑运算符 & && (短路与:当多个&&出现时,一旦发现一个flase,停止运算 返回false。) | || (短路或:当多个||出现时,一旦发现一个true,停止运算 返回 true。) !,关系运算符 == < <= > >= != ,位运算符& | ^ ~(不存在短路与,短路或),移位运算符:>> << >>>
(异或:相同为0,不同为1)
一元运算符
二元运算符
三元运算符 ? (true):(flase)
多个式子运算时:
1.排除法:先找优先级最低的,考虑结合性
2.结合计算:
实现现实中的逻辑(顺序,循环,分支(并列)三种结构)
switch case final(多的话,用switch,少的用 if )
if else
for (起始 结束 自增)起始条件不成立,不影响结束条件的判断(循环起别名(标识))
for循环的执行顺序(注int i=1;可以写函数调用)
while 起始 结束 自增量
do while
foreach
拥有一段特殊功能的代码。函数的作用:提高程序的安全性,复用性,健壮性,可读性,节省内存。
函数的参数,返回值,类型
public static int mytest() {
return (float)0;
}(错误)
全局变量:相对的概念。比局部变量更大的范围
成员变量:在堆区,创建有默认值。
局部变量:在栈区,没有默认值。
函数:在栈区。
对象:在堆区。
在java中内存分为
堆:实体,整型默认为0,布尔型默认是false。(内存中的一块区域,使用的底层队列结构)
栈:函数,局部变量,先进后出,使用完立刻释放(内存中的一块区域,使用的底层栈结构)
方法区,本地方法区,寄存器
释放机制:栈使用完立刻释放,堆里面的东西(通过垃圾回收机制释放)
递归:时间和空间的负责度(尽量避免递归)
重载:在同一类中,方法名相同,参数的个数,位置,类型不同,(与返回值无关)。作用:方便函数的编写,程序的执行。(构造方法)
数组:存储多个数字;定义:可以同时存储多个相同类型的数据,他是引用数据类型,数组是被放在堆区的,有默认值,
构成:new + 数据类型 + [元素的个数]
new :在堆内开辟空间,将数组的地址返回
int代表元素的数据类型
[3];代表数据的个数
我们可以通过一个变量保存数组的地址,这个变量的类型是int型的数组类型.
注意:int+[]是一个整体,代表一种数据类型,不能拆开.[]中也不能写数.
int[] arr = new int[3];
解释:先拿arr(引用类型)中保存的地址找到数组,然后在根据下标找到具体的元素,完成赋值或者取值
如果下标超出了数的范围,会报下标越界异常
java.lang.ArrayIndexOutOfBoundsException
引用数据类型和基本数据类型:一个是值,一个是地址(16进制)new在堆区里动态开辟空间。存储地址的类型(引用数据类型)
第一个元素的地址充当整个数组的地址(数组的内存是连续的,所以数组有下标。)
初始化赋值创建
int[] arr1=new int[]{4,5,7};
int[] arr2= {5,7,8,9};//自动(new,分配空间)
数组作为参数的时候不能直接使用大括号的方式。
在进行值传递的时候,函数里面无法影响的函数外
在进行址传递的时候,函数里面可以影响的函数外
一维数组:首地址
二维数组:多个一维数组的地址。
[外链图片转存失败(img-iwyAvUD9-1568960839567)(C:\Users\zhaoboshi\AppData\Roaming\Typora\typora-user-images\1563937957499.png)]
int[][] arr3 ={{4,5},{3,4,5,6}};
int[][] arr2=new int[2][4];
arr2[0] = new int[3];
arr2[1] = new int[] {3,4,5};
arr2[2] = new int[3];
平均时间复杂度(牺牲空间,调高时间复杂度,提升用户体验)
插入排序O(n^2)
冒泡排序
O(n^2)(循环首选最大值,俩个数比较)
选择排序
快速排序O(n log n)
堆排序O(n log n)
归并排序O(n log n)
基数排序O(n)
希尔排序O(n^1.25)
这些算法的思想的在这不做详细的介绍了:(但这些基础的排序很重要也很基础,可自己查询)
思想:封装,继承,多态
面向过程:强调的是功能行为:关注的是解决问题需要哪些步骤
面向对象:将功能封装进对象,强调具备功能的对象。关注的是解决问题需要哪些对象
面向对象是基于面向过程的。面向对象是符合人们思想的思想,可以使开发者有执行者变为指挥者。
可以将复杂的事情简单化
类是对象的抽象
对象<------------------------>类(万物皆对象)
对象是类的实现
类:类名,大驼峰原则
属性,成员变量
行为,成员方法 小驼峰原则
拥有相同(或者相似)属性和行为的对象都可以抽象出一个类
在创建对象时(new),调用构造方法,构造方法会对成员变量初始化(空参构造方法 ,整型0 ,引用为null)。(创建对象时的保存对象地址的变量在栈里)(方法在栈里调用)。如果没有引用的对象(可以被垃圾回收机制回收,匿名对象)
匿名对象的作用:节省代码,节省内存。
应用场所:作为参数传递
数组就是特殊的对象。
一个类型一旦创建出来,就是一个独立的数据类型,在他可见的范围内都是可以使用的,包括内部。
属性:权限
static修饰成员的功能 :静态成员变量,引用可以调用静态(推荐使用类名调用)类名无法调用非静态的属性;非静态的成员变量只能用引用调用。
1.在创建对象的时候会赋默认值
2.可以在类中定义变量的时候,直接赋值
3.非静态的成员变量可以在除了static修饰的方法外任何地方使用.
1.作用域:成员变量是整个对象.局部变量是从定义开始到所在的函数/if/for结束
2.默认值:成员变量会有默认值,局部变量没有默认值,要想使用必须先赋值
3.释放机制:成员变量跟对象保持一致,通过垃圾回收机制回收,局部变量使用完立即释放
4.存放的位置:成员变量放在堆区中的对象中,局部变量放在栈区中的方法中.
static:这是一个关键字,被static修饰的成员就变成了静态的.具有保值功能
一个类对应一个字节码文件,
静态方法区:类变成一个.class文件,当类中存在静态属性和方法时,静态属性和方法会被复制(从.class文件中)一份放在静态方法区(通常认为静态方法区在方法区的独立空间)对象的堆空间里只存在非静态的方法和属性。
类调用静态属性时,是字节码文件(.class)调用的静态对象(字节码文件是一个对象(特殊对象))。
静态的成员方法和非静态的成员方法优先使用静态的成员方法。效率高,节省内存。除一种(当方法中使用非静态的属性(成员变量),只能是非静态的方法)
工具类:类似工具经常使用的时候,可以用static封装工具类
默认创建无参的构造方法。作用:在对象被创建的时候给属性赋值。
构造方法局部变量和成员变量相同时(就近原则,没有this时),this等于引用值(引用数据类型,等于当前的对象地址)。this()可以当做构造方法 ;
1.不能自己调用自己—死循环
2.不能相互调用,死循环
3.this充当构造方法时,必须放在第一行
4.this在作为方法的时候,只能充当构造方法,不能作为其他方法
5.this的使用范围就是当前类的内部
随着对象的加载而加载,优先于构造方法之前,对象每创建一次执行一次。{}
父子类静态代码块的加载,父类静态代码块在前。
随着类的加载而加载,优先于main,整个程序执行过程中只执行一次。static{}
通过对具体属性的封装实现的,把对成员变量私有话,通过范围修饰词:private,增加安全性,复用性和可读性。
set get (约定规则,统一规范,方便使用)
脏数据:我们把程序中出现的不符合逻辑的数据称为脏数据
原因:让用户直接将数据传给了成员变量
解决:1.不让他直接传值----将成员变量私有化,写一个公共的方法
2.对数据进行过滤,将过滤后的数据交给成员变量
关键字:extend 继承的源object
功能:减少代码,多态的前提,方便操作,增加复用性,可读性,安全类。
首先从自己的方法里找,如果没有,就会从父类开始往上寻找。
(返回值为类型时,可以为父子关系):从父类继承中的方法中(增加了特殊功能),重写方法的返回值可以与父类的相同,也可以是父类的子类
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
最常用的地方就是构造器的重载。
重载规则:
被重载的方法必须改变参数列表(参数个数或类型不一样);
代表的是当前对象的父类,可以调用父类的方法和属性。但是它不是引用数据结构。在子类构造方法中,默认是有super();调用父类的空参构造方法。(new 子类的时候,也创建了父类对象)
可以修饰的内容:
1.类:final修饰的类不能有子类
2.成员变量:final修饰的变量是一个终值,不能再被改变,所以必须赋值。
3.局部变量:被final修饰的局部变量是一个终值,不能被再改变
4.方法:final修饰的方法不允许重写
5.空白final ------(final在定义成员变量的时候,可以在构造方法中赋值(即在定义时可以不赋值,但是在构造方法中必须赋值))
public static void main(String args[]){
}
(创建对象的四种方式:new ,克隆,反序列化,反射)
1.要想使用clone方法完成克隆,当前类必须实现了Cloneable这个接口
2.要想使用必须要重写这个方法
3.不是所有系统类都实现了他.比如Object,Integer,String等.实现了他的有ArrayList,LinkedList
4.clone没有调用new方法和构造方法.克隆不会调用构造方法,克隆时,根据源对象类型先分配和源对象相同的内存,然后将源对象中的各个域中数据拷贝过来,最后返回对象地址。new时,第1步也是先分配内存,然后调用构造方法初始化数据,最后将对象地址返回,
外界就可以通过这个对象地址(引用)操作此对象。
5.调用clone没有办法实现完全的深拷贝.对于调用clone的对象是深拷贝,但是对于他的成员默认还是浅拷贝,
如果想让成员也深拷贝,就要在重写的clone方法中调用成员的clone方法,依次类推.
比较地址。容错处理。(重载,如果俩个重载方法,类型是父子关系,俩个方法都可以执行,存在优先级。)
垃圾回收,
返回此object的运行时类,字节码文件对象 ,字节码文件对应的类(Class)。字节码文件对象对应字节码文件(.class这个属性也可以获得字节码文件对象)
jvm中类加载器生成字节码文件对象
应用:对象的身份证。
默认调用(打印报名+@+hash码)
抽象类中可以没有抽象方法;有抽象方法的类一定是抽象类。
继承的子类要么也是抽象类,要么是实现父类的抽象方法。
抽象类不能直接创建对象,必须通过子类实现,所以抽象类一定有子类。
抽象类的作用:
1抽象方法是没有实现的方法,抽象方法类似于规则声明(制定规则),可以制定一批规则。
2.可以节省代码
抽象类是介于接口和类之间。
比较:final,abstract,static,private
abstract(不能直接调方法,必须继承)和final(不能继承,不能重写)和static(类,调用)和private不能共用。
不能与abstract同时存在的关键字
1.final:被final修饰的类不能有子类,方法不能重写,但是abstract必须有子类,必须重写
2.static:修饰的方法可以通过类名调用,abstract必须通过子类实现
3.private:修饰的方法不能重写,abstract必须重写
接口也是抽象的
类<—>类(继承) extends
类<—>接口(实现)implements
成员变量:默认public,final,static(类型)符号常量。
成员方法:默认是public,abstract
单继承,多实现。
接口与接口之间的继承是继承。(接口同名的方法在类中可以实现(接口俩个方法实现没有区别))。
一般父类中放的是主要功能,接口中放的是额外的功能,接口作为父类的补充。
从jdk1.7 开始,以后的接口中可以有方法的实现,但是方法必须使用static或default修饰(接口同名的方法(实现不同方法(也可能是一个实现,一个是抽象的))在类中使用时必须重写(即俩个接口的实现方法都不取,自己实现)
接口的子类重写方法注意事项:
如果一个类实现两个接口,这两个接口同时有相同的抽象方法,在类中只需要重写一次这个方法。
如果接口中有default修饰的方法不需要重写。
如果两个接口里的方法名相同都是default方法,里面的方法体不同,在类中需要重写该方法。
如果两个接口中方法名,参数都相同的方法,一个接口是抽象方法,另一个是default修饰有方法体。这时该类也必须重写该方法。
面向接口编程:一个类声明一个接口(接口暴露,类不暴露实现)
设计模式:前人总结出来的对一些常见问题的解决方案,后人直接拿来使用.
常用的设计模式:单例,工厂,代理,适配器,装饰,模板,观察者等,一共有23种
分析:
1.我们肯定要建立一个单例类来描述
2.只允许有一个对象
3.全局的访问点:说的就是当前的s----通过static实现的
4.提供出去
5.给大家使用
作用:
1.传值
2.作为全局的访问点.
使用单例传值的好处:
好处:可以让两个对象在完全没有关系的前提下,实现值的传递,降低了耦合性,提高了内聚性
耦合性,内聚性在微观上说:描述的是类与类之间的关系
好处:我们应该尽量提高内聚性,减少耦合性,可以提高程序的健壮性,增加代码的可移植性,方便实现模块儿化编程
如何做到低耦合高内聚?
在处理类与类关系的时候,让类之间的关系越紧密耦合性越高,内聚性越低.反之,关系越松散耦合性越低,内聚性越高.
注意:在单例中一般只有向外提供s的方法是静态的,其他的都是非静态的.
通过static修饰对象名(当对象有被对象名指向时,垃圾回收机制不会清除)长期保存对象(垃圾回收机制)。
单例类的功能,可以将一个类的局部方法变成全局方法,可以传值(减少类和类之间的关系,高内聚(模块之间完成工作),低耦合(模块与模块之间的联系)),建立全局访问点。
饿汉式
final static *** ** = new **();
private 构造()
public static get***Instance()
{return **;}
懒汉式
static *** ;
private 构造()
public static get***Instance{
(if(**==null)
{** = new **()}
return **;)
}
典型单例类runtime()
package com.work.day4;//测试jvm的内存
public class RunTimeTest {
public static void main(String[] args) {
Runtime time=Runtime.getRuntime();
System.out.println(time.freeMemory()/1024./1024.);
System.out.println(time.totalMemory()/1024./1024.);
System.out.println(time.maxMemory()/1024./1024.);
}
}
适配器设计模式<----httpservlet之前,三个类构成适配器模式,httpservlet,和myservlet使用模板模式
servlet->(实现,重写5个方法)GenervalServlet->(继承,重写需要的方法)HttpServlet->(继承,重写需要的方法)myservlet
多态:一种事物的多种形态.
前提是:继承。用法:用父类(不一定是直接的)的引用指向子类对象。
实现动态的手段:动态类型,动态绑定,动态加载。
程序运行分成三个阶段:预编译,编译,运行
预编译:程序打开的时候,活儿已经干完了.(预处理命令 #define)
编译:从打开程序开始到点击左上角的三角之前—只能识别前面的引用类型,不会识别后面的对象
运行:从点击三角开始—真正的识别对象,对象开始干活儿
多态:我们在编译阶段不能确定具体的对象类型,只有运行阶段才知道干活的对象
object :动态类型 动态绑定:(库运行时,确定库的内容)
总结:优点:可以提高代码的扩展性,使用之前定义好的功能,后面直接拿来使用,不用再创建新的方法.
缺点:只能直接调用父类有的方法,不能直接调用子类特有的方法.
环境::多态的环境
下,说向上转型,向下转型。
注意:是在多态的前提下再说向上转型,向下转型.
向上转型:相当于是自动类型转换.多态本身就是向上转型.
作用:实现多态
向下转型:相当于强制类型转换
作用:解决多态中无法调用子类特有属性的缺点.
运算符:instanceof (使用前提:前后必须有关系)
原理说明:确定当前的对象是否后面的类和子类的对象,是返回true,不是返回false
作用:容错处理,增加用户体验
多态下成员的使用: !!!!!!方法相同编译看父类,运行看子类
public static void main(String[] args) {
/*
* 继承
*/
Zi zi = new Zi();
zi.show();
zi.eat();
System.out.println(zi.age);//10,继承中子类与父类出现同名的属性,父类的会被覆盖掉
//多态
/*
* 当父类与子类有同名属性或方法时
* 成员变量:编译的时候能不能访问看父类,运行的时候也看父类
* 成员方法:编译的时候能不能访问看父类,运行的时候看子类
* 静态成员方法:编译运行都看父类
*/
Fu fu = new Zi();
System.out.println(fu.age);
fu.show();
}
当父类与子类有同名的方法或属性时:(多态)
成员变量:编译的时候能不能访问看父类,运行的时候也看父类
成员方法:编译的时候能不能访问看父类,运行的时候看子类
静态成员方法:编译的时候能不能访问看父类,运行的时候也看父类
内部类:定义在一个类的内部的类,内部类的地位与外部类的成员变量,成员方法平等。内部类也可以看做是外部类的成员。
public class Demo14 {
public static void main(String[] args) {
Outer outer = new Outer();
outer.age = 10;
//调用内部类成员的方式
//两种
//第一种:借助于外部类的方法实现
outer.show();
//第二种:直接在这里调用
//引用:外部类.内部类
//构成:外部类对象的引用.new 内部类的构造方法
Outer.Inner inner = outer.new Inner();
inner.eat();
}
}
class Outer{
int age;
//内部类
class Inner{
int height;
public void eat() {
System.out.println("eat");
}
}
public void show() {
System.out.println("show");
Inner inner = new Inner();
inner.eat();
}
}
内部类:间接使用多继承
class A1{
}
class B1{
}
//说明功能
//我们可以通过内部类让java间接实现多继承
class X extends A1{
class Y extends B1{
}
}
定义:定义在一个类的方法里的类,
作用:功能私有化,增加代码的可读性和可操作性。
局部内部类:定义在一个类方法中的类
final:被final修饰的变量会被放在常量区,而常量区的值存在的时间要大于局部变量所在的方法,相当于从原来的基础上扩大了作用域
静态内部类不一定有静态方法,有静态方法的一定是静态内部类。
public class Demo17 {
public static void main(String[] args) {
// Out out = new Out();
// Out.Inn inn = out.new Inn();
//创建静态内部类对象
//构成: new + 外部类名字.内部类的构造方法
Out.Inn inn = new Out.Inn();
//调用方法
inn.play();
//调用静态方法
// inn.show();
Out.Inn.show();
}
}
定义:定义在一个类方法中的
匿名内部类(对象):定义在一个类方法中的匿名子类对象,属于局部内部类
//匿名内部类作为参数
public void canShuTest1() {
System.out.println(
new Animal() {
public void eat() {
// TODO Auto-generated method stub
super.eat();
}
@Override
public String toString() {
return "haha";
}
}
);
Math
package com.ali.test;
import java.util.Random;
/*
* Math:装的是用于数学的计算方法
*/
public class Demo13 {
public static void main(String[] args) {
System.out.println(java.lang.Math.abs(-10));//绝对值
System.out.println(java.lang.Math.cos(3.14159));//三角余弦
System.out.println(java.lang.Math.ceil(3.4));//向上取整
System.out.println(java.lang.Math.floor(3.4));//向下取整
System.out.println(java.lang.Math.random());//随机数 [0,1.0)
//求[0,10)之间的整数
System.out.println((int)java.lang.Math.floor(java.lang.Math.random()*10));
//Random类
//求[0,10)之间的整数
Random random = new Random();
System.out.println(java.lang.Math.abs(random.nextInt()%10));
System.out.println(random.nextInt(10));//直接获取的是[0,10)之间的数
}
}
BigInteger(嵌套了math,可以直接使用math的方法)
包装类:专门将简单数据类型的数据类型,形成的对应的类
简单数据类型 包装类
byte Byte
short Short
int Integer
long Long
char Character
如果想字符串转换数字,必须是数值型字符串。
简单数据类型->包装类(装箱 Integer integer1=new Integer(5));
包装类->简单数据类型(拆箱 int value = integer1.tovlaue)
jdk1.5开始可以实现自动装箱,拆箱。
/*
* 包装类:专门将简单数据类型的数据进行封装,形成的对应的类.
* 简单数据类型 包装类
* byte Byte
* short Short
* int Integer
* long Long
* float Float
* double Double
* boolean Boolean
* char Character
*/
public class Demo10 {
public static void main(String[] args) {
// 基本类型转成字符串类型
// static String Integer.toString(int i)
// static String Double.toString(double d)
String value1 = Integer.toString(12);
System.out.println(value1+2);
// 字符串类型转基本类型
// int Integer.parseInt("23")
// double Double.parseDouble("3.45")
//注意:这里的字符串必须是数值型的字符串
int a = Integer.parseInt("234");
System.out.println(a+2);
//
// 把十进制转成其它进制
// Integer.toHexString() 十六进制
// Integer.toOctalString() 八进制
// Integer.toBinaryString() 二进制
System.out.println(Integer.toHexString(10));
System.out.println(Integer.toOctalString(10));
System.out.println(Integer.toBinaryString(10));
// 把其它进制转十进制
// Integer.parseInt(数据,进制)
System.out.println(Integer.parseInt("10",2));
}
}
//注意点:在一个字节范围内前面定义好的,后面再定义,直接使用前面的.
// Integer integer4 = 100;
// Integer integer5 = 100;
// System.out.println(integer4 == integer5);//true
//如果超过了一个字节的范围,就认为是两个数,要独立占用两块儿内存空间.
Integer integer4 = 1000;
Integer integer5 = 1000;
System.out.println(integer4 == integer5);//false
即在包装类中,如果数据比较小(一个字节),认为是一个对象(值相同,即使new了俩个对象。)
也是一个特殊的类(创建对象,调用方法)
package com.ali.test;
/*
* 枚举
* 默认对应的是数字.数字从0开始计数
* 枚举是一个被命名的整型常数的集合,用于声明一组带标识符的常数。
* 枚举在曰常生活中很常见,例如一个人的性别只能是“男”或者“女”,一周的星期只能是 7 天中的一个等。
* 类似这种当一个变量有几种固定可能的取值时,就可以将它定义为枚举类型。
在 JDK 1.5 之前没有枚举类型,那时候一般用接口常量来替代。
而使用 Java 枚举类型 enum 可以更贴近地表示这种常量。
*/
enum EnumTest{
First,
Second,
Third,
Fourth,
Fifth,
Sixth
}
public class Demo12 {
public static void main(String[] args) {
EnumTest test = EnumTest.Fifth;
System.out.println(test.compareTo(EnumTest.First));
switch (test.compareTo(EnumTest.First)) {
case -1:
System.out.println("不相等");
break;
case 0:
System.out.println("相等");
break;
case 4:
System.out.println("不相等");
break;
default:
System.out.println("hah");
break;
}
System.out.println(EnumTest.First);
System.out.println(test.getDeclaringClass().getName());//字节码文件对象
System.out.println(test.name());
System.out.println(test.toString());
System.out.println(test.ordinal());
}
}
定义:程序当中出现的不正常的情况;
异常的由来:程序在运行时出现了不正常的情况,java提取了对应的属性,名字,原因等,形成异常对象,进而形成了各种异常类
异常的分类:(throwable)
1.Error(错误):运行中出现的严重错误,不需要我们进行更改
2.Exception:运行中出现的不严重的错误,我们可以尝试去更改。
Exception:分类
第一种分类:系统异常,系统提前定义好的,我们直接使用
自定义异常:需要自己定义
第二种分类:编译阶段抛出的异常:
运行阶段抛出的异常:大部分使用的异常。(在写代码的时候不需要的处理,手动避免)
运行阶段出现的错误:会在此处产生一个异常对象,如果此处没有处理异常的机制(能力),能继续往上抛,一直的到jvm,jvm会报错。
public class Demo1 {
public static void main(String[] args) {//4.这里也没有处理异常的能力,继续往上抛,抛给JVM.
//JVM会调用异常类的打印方法,将异常的信息打印到控制台
Math math = new Math();
int value = math.div(3, 0);//3.这里也没有处理异常的能力,继续往上抛
System.out.println(value);
}
}
class Math{
public int div(int a,int b) {//2.div方法也没有处理异常的能力,继续往上抛
return a/b;//1.会自动生成一个异常类对象(new ArithmeticException()) ,这里没有打印的能力,程序会将异常抛出,抛给
//他所在的方法
}
}
异常的特点:程序出现异常的时候,会打印异常的信息并中断程序的进行,所以当有多个异常同时出现的时候,默认只能执行第一个.
try catch
catch会对try里面的代码进行监听,如果try里面的代码没有异常,catch不会执行,会直接执行后面的代码
如果try里面的代码发生了异常,catch会立刻捕获(效果:try里面的代码会立刻中断,直接执行catch)
try{
可能发生异常的代码
}catch(Exception e){ //捕获异常 e就是要捕获的异常
对当前异常的处理
}
try {
int value = math.div(3, 0);//3.这里也没有处理异常的能力,继续往上抛
//注意:只要try内部的代码发生了异常,catch会立刻捕获异常,马上执行catch,所以发生异常后的代码不会执行.
//只有try里面的代码没有发生异常,这里的代码才能执行
System.out.println("haha:"+value);
}catch (Exception e) {//e = new ArithmeticException() 多态
//对异常进行处理
//e.printStackTrace();//打印异常的位置,原因,名字
//System.out.println(e.getMessage());//打印原因
System.out.println(e.toString());//打印原因,名字
}
多重处理(多个异常):try catch catch finally//必须执行的操作(例如:关闭数据库):主要用于资源的释放等。
catch会对try里面的代码进行监听,如果try里面的代码没有发生异常,catch不会执行,会直接执行后面的代码.
如果try里面的代码发生了异常,catch会立刻捕获(效果:try里面的代码会立刻终端,直接执行catch)
try{
可能发生异常的代码
}catch(异常一 e){ //捕获异常 e就是要捕获的异常
对当前异常的处理
}catch(异常二 e){ //捕获异常 e就是要捕获的异常
对当前异常的处理
}catch(Exception e){ //捕获异常 e就是要捕获的异常
对当前异常的处理
}
(return 结束不了,finally还能执行)
System.exit(0)?/退出程序,
finally不能执行了
这个结构跟异常没有关系
try{
获取资源
}finally{
释放资源
}
自定义异常:常见:订单异常,用户异常,素数异常
什么是自定义异常:自己定义的异常类,由于Exception已经有了异常的基本功能,所以一般写的是他的子类
为什么要自定义异常?
系统没有定义的异常需要我们自己来定义,我们要解决的是系统没有解决的问题
分类:
编译异常:发生在编译阶段.—对应的异常是除了RumtimeException之外的所有异常
特点:对异常进行处理的所有工作都要我们手动完成
运行时异常:发生在运行阶段.—RumtimeException
特点:所有的工作我们都可以不管
常见的自定义异常:订单异常 用户异常 负数异常
以负数异常为例:
对于编译异常需要我们进行处理的有:
异常类的创建----FuShuException
异常对象的创建—应该是在发生异常的位置
异常对象的抛出—throw
异常的声明(我们要给可能发生异常的方法进行异常的声明)----throws
作用:告诉别人我有可能发生异常
package com.ali.test;
//为了解释FuShuException构造方法中的参数如何在打印方法中显示.
public class Demo7 {
public static void main(String[] args) {
Teacher teacher = new Teacher("除数为负数了");
teacher.printStackTrace();
}
}
class Person{//相当于Exception
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String message) {
super();
this.message = message;
}
public void printStackTrace() {
System.out.println(this.getMessage());
}
}
//相当于FuShuException
class Teacher extends Person{
public Teacher() {
}
public Teacher(String message) {
super(message);
}
}
特点:所有的工作我们都可以不管
常见的自定义异常:订单异常 用户异常 负数异常
以负数异常为例:
对于编译异常需要我们进行处理的有:
异常类的创建----FuShuException
异常对象的创建—应该是在发生异常的位置
异常对象的抛出—throw
异常的声明(我们要给可能发生异常的方法进行异常的声明)----throws
作用:告诉别人我有可能发生异常
package com.ali.test;
//为了解释FuShuException构造方法中的参数如何在打印方法中显示.
public class Demo7 {
public static void main(String[] args) {
Teacher teacher = new Teacher("除数为负数了");
teacher.printStackTrace();
}
}
class Person{//相当于Exception
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String message) {
super();
this.message = message;
}
public void printStackTrace() {
System.out.println(this.getMessage());
}
}
//相当于FuShuException
class Teacher extends Person{
public Teacher() {
}
public Teacher(String message) {
super(message);
}
}