狂神说Java---JavaSE重点内容(持续更新中)
一.安装开发环境
卸载JDK
1.删除Java的安装目录
2.删除JAVA_HOME
3.删除path下关于java的目录
4.java(空格)-version
安装JDK
1.百度搜索JDK8,找到下载地址
2.同意协议
3.下载电脑对应的版本
4.双击安装JDK
5.记住安装的路径
6.配置环境变量
1.我的电脑-->右键-->属性
2.配置环境变量(注意是在系统变量里)-->新建系统变量且变量名为JAVA_HOME(只能是这个),变量值为jdk目录(举个例子:F:\Environment\java\jdk1.8)

3.配置path变量(注意也是在系统变量里):
1.)双击系统变量中的Path变量(%%表示引用路径),点击新建,变量值为%JAVA_HOME%\bin(只能是这个)
2.)再次点击新建,变量值为%JAVA_HOME%\jre\bin(只能是这个)

7.测试JDK是否安装成功
1.打开cmd
2.输入java -version,若成功,如下图所示(以java8为例)

二.Java基础语法
1.所有字符的本质还是数字 所以char类型可以强制转换为int类型
2JDK7新特性,数字之间可以用下划线分割
int money=10_0000_0000 输出结果为1000000000
3.(1)实例变量:从属于对象;如果不自行初始化,这个类型的默认值 0
(2)布尔值:默认false
(3)除了基本类型,其余的默认值都是null
4.final定义常量(一般用大写字母表示)
5.修饰符不存在先后顺序 比如:public static final double PI =3.14
6.变量命名的规范
(1)类成员变量、局部变量、方法名采用驼峰命名法,即除了第一个单词以外,后面的单词首字母大写 如lastName
(2)常量大写字母和下划线
(3)类名采用第一个单词大写的驼峰命名法
7.idea快捷键
ctrl+D 复制当前行到下一行
8.单词case 转换
9.幂运算
double pow = Math.pow(2,3) //2的三次方
10.int a = 10;
int b = 20;
System.out.println(""+a+b);//空字符串在前,输出1020即字符串拼接
System.out.println(a+b+"");//空字符串在后,输出30,先进行相加运算
11.包
为了更好地组织类,Java提供了包机制,用于区别类名的命名空间
一般利用公司域名倒置作为包名
为了能够使用某一个包的成员,我们需要在Java程序中明确导入该包,使用"import"语句可完成此功能
12.看《阿里巴巴开发手册》,规范自己的代码,养成良好的习惯
13.JavaDoc在线文档 :https://docs.oracle.com/javase/8/docs/api/
/**
*@author KuangShen
*@version 1.0
*@since 1.8
*/
/**
*
*@param
*@return
*/
三.Java流程控制
1.Scanner类
作用:获取用户的输入
通过Scanner类的next()与nextLine()方法获取输入的字符串,在读取前我们一般需要使用hasNext()与hasNextLine()判断是否还有输入的数据
import java.util.Scanner;//调用Scanner类
基本语法:
(1)Scanner s = new Scanner(System.in);//创建一个扫描器对象,用于接收键盘数据
(2)//判断用户有没有输入字符串
if(scanner.hasNext()){
//使用next方式接收
(3)//接收字符串
String str = scanner.next();
System.out.println("输出内容为:"+str);
}
(4)scanner.close(); //凡是属于IO流的类如果不关闭会一直占用资源,要养成好习惯用完就关掉
next():
1).一定要读取到有效字符后才可以结束输入。
2).对输入有效字符之前遇到的空白,next()方法会自动将其去掉。
3).只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
4).next()不能得到带有空格的字符串。
nextLine():
1).以Enter为结束符,也就是说nextLine()方法返回的是输入回车之前的所有字符。
2).可以获得空白。
1 import java.util.Scanner; 2 3 public class Demo1 { 4 public static void main(String[] args) { 5 //我们可以输入多个数字,并求其总和与平均数,每输入一个数字用回车确认,通过输入非数字来结束输入并输出执行结果。 6 Scanner scanner = new Scanner(System.in); 7 double sum = 0;//和 8 int m = 0;//计算输入了多少个数字 9 while(scanner.hasNextDouble()){ //通过循环判断是否还有输入,并在里面对每一次进行求和和统计 10 double x =scanner.nextDouble(); 11 m = m + 1; 12 sum = sum + x; 13 System.out.println("你输入了第"+m+"个数据,然后当前结果sum="+sum); 14 } 15 System.out.println(m+"个数的和为"+sum); 16 System.out.println(m+"个数的平均值是"+(sum/m)); 17 } 18 }

2.if选择结构
if多选择结构:if...else if...else if...else
嵌套选择结构:if(){
if()
......
}
3.switch多选择结构
swithch语句中的变量类型可以是:
1).byte、short、int或者char。
2).从JavaSE 7 开始,switch支持字符串String类型了,同时case标签必须为字符串常量或字面量
1 import java.util.Scanner; 2 public class Demo2 { 3 public static void main(String[] args) { 4 Scanner scanner = new Scanner(System.in); 5 char grade = scanner.next().charAt(0); 6 switch(grade){ 7 case 'A': 8 System.out.println("优秀"); 9 break; 10 case 'B': 11 System.out.println("良好"); 12 case 'C': 13 System.out.println("及格"); 14 case 'D': 15 System.out.println("再接再厉"); 16 case 'E': 17 System.out.println("挂科"); 18 default: 19 System.out.println("未知等级"); 20 } 21 } 22 }


1 import java.util.Scanner; 2 public class Demo2 { 3 public static void main(String[] args) { 4 Scanner scanner = new Scanner(System.in); 5 String name = scanner.nextLine(); 6 switch (name){ 7 case "秦疆": 8 System.out.println("秦疆"); 9 break; 10 case "狂神": 11 System.out.println("狂神"); 12 break; 13 default: 14 System.out.println("弄啥嘞!"); 15 } 16 } 17 }
4.反编译
接下来看一个骚操作,叫“反编译” java---class(字节码文件)---反编译(IDEA)
还是上述的代码,将Demo.class字节码文件拖入IDEA中(在文件资源管理器中复制粘贴,不能直接在IDEA中),结果为下:
1 // 2 // Source code recreated from a .class file by IntelliJ IDEA 3 // (powered by FernFlower decompiler) 4 // 5 6 import java.util.Scanner; 7 8 public class Demo2 { 9 public Demo2() { 10 } 11 12 public static void main(String[] args) { 13 Scanner scanner = new Scanner(System.in); 14 String name = scanner.nextLine(); 15 byte var4 = -1; 16 switch(name.hashCode()) { 17 case 941788: 18 if (name.equals("狂神")) { 19 var4 = 1; 20 } 21 break; 22 case 997472: 23 if (name.equals("秦疆")) { 24 var4 = 0; 25 } 26 } 27 28 switch(var4) { 29 case 0: 30 System.out.println("秦疆"); 31 break; 32 case 1: 33 System.out.println("狂神"); 34 break; 35 default: 36 System.out.println("弄啥嘞!"); 37 } 38 39 } 40 }
5.while循环
1).结构:while(布尔表达式){
//循环内容
}
2).只要布尔表达式为true,循环就会一直执行下去。
3).我们大多数情况是会让循环停止下来的,我们需要一个让表达式失效的方式来结束循环。
4).少部分情况需要循环一直执行,比如服务器的请求响应监听等。
5).循环条件一直为true就会造成无限循环(死循环),我们正常的业务编程中应该尽量避免死循环,会影响程序性能或者造成程序卡死崩溃!
6.for循环
练习1:用for循环输出1-1000之间能被5整除的数,并且每行输出3个(小技巧,在idea中输入1000.for就能直接得到for循环)
1 public class Demo2 { 2 public static void main(String[] args) { 3 for (int i = 0; i <= 1000; i++) { 4 if(i%5==0){ 5 System.out.print(i+"\t"); 6 } 7 if (i%(5*3)==0){ 8 System.out.println(); 9 } 10 } 11 } 12 }


练习2 打印九九乘法表
1 public class Demo2 { 2 public static void main(String[] args) { 3 for (int i = 1; i <=9 ; i++) {//一共九行 4 for (int j = 1; j <=i ; j++) {//每行有多少个式子 5 System.out.print(i+"*"+j+"="+(i*j)+"\t"); 6 } 7 System.out.println(); 8 } 9 } 10 }

7.增强for循环
1 public class Demo2 { 2 public static void main(String[] args) { 3 int [] numbers = {10,20,30,40,50}; 4 for(int x:numbers){ 5 System.out.println(x); 6 } 7 } 8 }
8.break continue
1).break在任何循环语句的主体部分,均可用break控制循环的流程,break用于强行退出循环,不执行循环中剩余的语句。(break语句也在switch语句中使用)
2).continue语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定。
9.打印三角形
1 public class Demo2 { 2 public static void main(String[] args) { 3 for (int i = 1; i <= 5; i++) { 4 for (int j = 5; j >=i; j--) { 5 System.out.print(" "); 6 } 7 for (int j = 1;j <=i;j++){ 8 System.out.print("*"); 9 } 10 for(int j =1;j <i;j++){ 11 System.out.print("*"); 12 } 13 System.out.println(); 14 } 15 } 16 }

四.Java方法详解
1.命令行传递参数(注意运行的是com.kuang.method.Demo03 而不是Demo03)

2.可变参数
在方法声明中,在指定参数类型后加一个省略号(...)。
一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
1 public static void printMax(double...numbers){ 2 if(numbers.length == 0){ 3 System.out.println("No argument passed"); 4 return; 5 } 6 double result = numbers[0]; 7 8 //排序! 9 for (int i = 1; i < numbers.length; i++) { 10 if(numbers[i]>result){ 11 result = numbers[i]; 12 } 13 } 14 System.out.println("The max value is "+result); 15 }
3.递归
A方法调用A方法,就是自己调用自己
利用递归可以用简单的程序来解决一些复杂的问题。它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。
递归结构包括两个部分;
递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。
递归体:什么时候需要调用自身方法。
阶乘例子:
1 public class Demo2 { 2 public static void main(String[] args) { 3 System.out.println(4); 4 } 5 public static int f(int n){ 6 if(n==1){ 7 return 1; 8 }else{ 9 return n*f(n-1); 10 } 11 } 12 }
五.Java数组
1.数组定义:相同类型数据的有序集合,描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。其中,每一个数据乘坐有个数组元素,每个数组元素可以通过一个下标来访问它们。
2.数组声明创建
1).首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法:
dataType[ ]arrayRefVar; //首选的方法
或
dataType arrayRefVar[ ]; //效果相同,但不是首选方法
2).Java语言使用new操作符来创建数组,语法如下:
dataType [ ] arrayRefVar = new dataType [arraySize];
3).数组的元素是通过索引访问的,数组索引从0开始
4).获取数组的长度:arrays.length
3.内存分析
1.)堆
存放new的对象和数组
可以被所有的进程共享,不会存放别的对象引用
2.)栈
存放基本变量类型(会包含这个基本类型的具体数值)
引用对象的变量(会存放这个引用在堆里面的具体地址)
3.)方法区
可以被所有的线程共享
包含了所有的class和static变量
4.三种初始化
1.)静态初始化
int [ ] a = {1,2,3};
Man [ ] mans = {new Man(1,1),new Man(2,2)};
2.)动态初始化
int [ ] a = new int [2];
a[0]=1;
a[1]=2;
3.)数组的默认初始化
数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。
5.数组的四个基本特点
1.)其长度是确定的,数组一旦被创建,它的大小就是不可以改变的。
2.)其元素必须是相同类型,不允许出现混合类型。
3.)数组中的元素可以是任何数据类型,包括基本类型和引用类型。
4.)数组变量属引用类型,数组也可以看成是对象,数组中的每一个元素相当于该对象的成员变量。数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是i其他对象类型,数组对象本身实在堆中的。
6.数组边界
1.)下标的合法区间:[0,length-1],如果越界就会报错;
2.)ArrayIndexOutOfBoundsException:数组下标越界异常!
3.)小结:数组是相同数据类型(数据类型可以为任意类型)的有序集合
数组也是对象。数组元素相当于对象的成员变量
数组长度是确定的,不可变的。
7.数组使用
1.)For-Each循环
for(int array : arrays){ }
2.)数组作方法入参
//打印数组元素
public static void printArray(int [] arrays){
for(int i = 0;i<arrays.length;i++){
System.out.print(arrays[i]+" ");
}
}
3.)数组作返回值
//反转数组
public static int[ ] reverse(int [ ] arrays){
for(int i = 0,j = result.length-1;i < arrays.length; i++,j--){
result[j] = arrays[i];
}
return result;
}
8.多维数组
1.)多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。
9.Array类
1.)数组的工具类java.util.Arrays
2.)由于数组对象本身并没有什么方法可以供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以堆数据对象进行一些基本的操作。
3.)查看JDK帮助文档
4.)Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而“不用”使用对象来调用(注意:是“不用”而不是“不能”)
5.)具有以下常用功能:
给数组赋值:通过fill方法。
对数组排序:通过sort方法,按升序。
比较数组:通过equals方法比较数组中元素值是否相等。
查找数组元素:通过binarySerach方法能堆排序好的数组进行二分查找法操作。
10.冒泡排序(注意,冒泡排序只能从小到大,如果想从大到小再写一个逆序输出数组的函数)
冒泡排序无疑是最为出名的排序算法之一,总共有八大排序!
1.)冒泡的代码还是相当简单的,两层循环,外层冒泡轮数,里层依次比较,江湖中人人尽皆知。
2.)我们看到嵌套循环,应该立马就可以得出这个算法的时间复杂度为O(n2).
3.)步骤
1.比较数组中,两个相邻的元素,如果第一个数比第二个数大,我们就交换他们的位置
2.每一次比较,都会产生出一个最大。或者最小的数字;
3.下一轮则可以少一次排序!
4.依次循环,直到结束!
1 import java.util.Arrays; 2 public class Demo2 { 3 public static void main(String[] args) { 4 int [] a = {1,4,7,2,3,12,9,10,100,8,10000,99,101}; 5 int [] sort = sort(a);//返回排序后的数组 6 System.out.println(Arrays.toString(sort)); 7 } 8 //冒泡排序 9 public static int[] sort(int [] array){ 10 int temp = 0; 11 //临时变量 12 //外层循环,判断我们要走多少次 13 for (int i = 0; i < array.length-1; i++) { 14 //内层循环,比较判断两个数,大的在右边,小的在左边,最右边的是最大值 15 for (int j = 0; j <array.length-1-i ; j++) { 16 if(array[j]>array[j+1]){ 17 temp = array[j]; 18 array[j] = array[j+1]; 19 array[j+1] = temp; 20 } 21 } 22 } 23 return array; 24 } 25 }

11.稀疏数组(后续会补充)
1.)党一个数组中大部分元素为0,或者为同一值得数组时,可以使用稀疏数组来保存该数组。
2.)稀疏数组的处理方式是:
记录数组一共有几行几列,有多少个不同值
吧具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模
3.)左图为原始数组,右图为稀疏数组


六.面向对象编程(OOP)
1.对于描述复杂的食物,为了从宏观上把握,从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理。
2.OOP的本质:以类的方式组织代码,以对象的组织(封装)数据。
3.三大特性:封装、继承、多态
4.static方法是和类一起加载,而普通方法则是和对象一起加载,所以static方法中只能调用static 方法而不能调用普通方法,但是普通方法一定能调用static方法,因为既然能调用普通方法,那么就说明存在对象,存在对象就说明一定存在类
5.1.)类:是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物。
2.)对象:是抽象概念的具体实例
6.构造器
1.)使用new关键字创建对象
2.)使用new关键字创建的时候,处理分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的使用。(使用new关键字,本质是在调用构造器)
3.)类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下两个特点:
必须和类的名字相同
必须没有返回类型,也不能写void
4.)alt + insert 可以快速创建构造方法
7.创建对象内存分析:

8.封装:
1.)该露的露,该藏的藏
我们程序设计要求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。
2.)封装(数据的隐藏)
通常,应禁止直接访问一个对象中的数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。
3.)属性私有,get/set(get()方法用来获取这个数据,set()方法用来设置数据)
思想就是把属性设置为私有,虽然在类外无法对属性进行操作,但是在类内部有可以对属性进行操作的方法

1 package Demo; 2 public class Person { 3 String sex; 4 String name; 5 int age; 6 public Person() { 7 } 8 public Person(String sex, String name, int age) { 9 this.sex = sex; 10 this.name = name; 11 this.age = age; 12 } 13 public String getSex() { 14 return sex; 15 } 16 public void setSex(String sex) { 17 this.sex = sex; 18 } 19 public String getName() { 20 return name; 21 } 22 public void setName(String name) { 23 this.name = name; 24 } 25 public int getAge() { 26 return age; 27 } 28 public void setAge(int age) { 29 this.age = age; 30 } 31 }
9.继承
1.)extends的意思是“扩展”。子类是父类的扩展。
2.)JAVA中类只有单继承,没有多继承!
3.)继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
4.)继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。
5.)子类和父类之间,从意义上讲应该具有“is a”的关系
6.)在Java中,所有的类都默认直接或间接继承Object类
7.)Suoer详解(先写知识点,后面用代码举例子):
super,print()的意思是,在子类中调用父类的方法,但是不可以是prqivate权限的。this.print()的意思是,调用子类自身的方法。
在子类中,用super()调用父类的构造方法,但是必须放在子类的第一行。
super必须只能在子类的方法或者构造方法中!
super和this不能同时调用构造方法!
8.)方法重写:需要有继承关系,子类重写父类的方法
方法名必须相同
参数列表必须相同
修饰符:范围可以扩大但是不能缩小
抛出的异常:范围可以缩小但是不能扩大
为什么需要重写:
父类的功能,子类不一定需要,或者不一定满足
Alt + Insert: Override
10.多态
1.)即同一方法可以根据发送对象的不同而采用多种不同的行为方式。
2.)一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多
3.)多态存在的条件:
有继承关系
子类重写父类方法
父类引用指向子类对象
4.)注意,多态是方法的多态,属性没有多态性。
1 public class Person { 2 3 } 4 5 6 public class Student extends Person{ 7 8 } 9 10 public class Demo3 { 11 public static void main(String[] args) { 12 Person a = new Student(); 13 } 14 }
5.)父类引用指向子类对象后,调用的方法必须得是子类父类都有的,不能调用子类特有的方法
6.)不能重写的方法:
static:属于类,不属于对象(实例)
final:常量,无法改变
private方法
这三种方法无法实现方法重写,所以无法实现多态
7.)instanceof 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例
boolean result = obj instanceof Class
其中 obj 为一个对象,Class 表示一个类或者一个接口,当 obj 为 Class 的对象,或者是其直接或间接子类,或者是其接口的实现类,结果result 都返回 true,否则返回false。
注意:编译器会检查 obj 是否能转换成右边的class类型,如果不能转换则直接报错,如果不能确定类型,则通过编译,具体看运行时定。
类型转换:
把子类转换为父类,向上转型
把父类转换为子类,向下转型(强制转换)
8.)静态导入包
import static java.lang.Math.random;
9.)抽象类
1.)abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类。
2.)抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类。
3.)抽象类,不能使用new关键字来创建对象,它是用来让子类继承的。
4.)抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的(子类重写)。
5.)子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。
10.)接口
1.)普通类:只有具体实现
2.)抽象类:具体实现和规范(抽象方法)都有!
3.)接口:只有规范!自己无法写方法---专业的约束 约束和实现分离:面向接口编程
4.)接口就是规范,定义的是一组规则,体现了现实世界中”如果你是...而必须能...“的思想。如果你是天使,则必须能飞。如果你是汽车,则必须能跑。如果你是好人,则必须干掉坏人;如果你是坏人,则必须欺负好人。
5.)接口的本质是契约,就像我们人间的法律一样。制定后大家都遵守。
6.)OO的精髓,是对对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计模式都只针对具备了抽象能力的语言(比如c++,java,c#等),就是因为设计模式所研究的,实际上就是如何合理的去抽象。
7.)声明类的关键字是class,声明接口的关键字是interface。
8.)接口中的所有定义其实都是抽象的,默认是public abstract
9.)通过implement实现接口,实现了接口的类,就需要重写接口中的方法。
10.)接口可以实现多继承
11.)接口作用:
约束
定义一些方法,让不同的人实现
public abstract
public static final
接口不能被实例化,接口中没有构造方法
implements可以实现多个接口
必须要重写接口中的方法
11.N种内部类

1 public class Outer { 2 private int id; 3 public void out(){ 4 System.out.println("这是外部类的方法"); 5 } 6 public class Inner{ 7 public void in(){ 8 System.out.println("这是内部类的方法"); 9 } 10 } 11 public static void main(String[] args) { 12 Outer outer = new Outer(); 13 //通过这个外部类来实例化内部类 14 Outer.Inner inner = outer.new Inner(); 15 inner.in(); 16 } 17 }
12.异常
1.)软件程序在运行过程中,非常可能遇到的这些异常问题,我们叫异常。英文是Exception,意思是例外。这些,例外情况,或者叫异常,怎么让我们写的程序做出合理的处理。而不至于程序崩溃。
2.)异常指程序运行中出现的不期而至的各种状况,如:文件找不到、网络连接失败、非法参数等。
3.)异常发生在程序运行期间,它影响了正常的程序执行流程。
4.)简单分类:
检查性异常:最具代表的检查性检查是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单忽略。
运行时异常:运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
错误:错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。
5.)体系结构
Java把异常当作对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类。
在Java API中已经定义了许多异常类,这些异常类分为两大类,错误Error和异常Exception。

6.)Error
Error类对象由Java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关。
Java虚拟机运行错误(Virtual MachineError),当JVM不再有继续执行操作所需的内存资源时,将出现OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止;
还有发生在虚拟机试图执行应用时,如类定义错误(MoClassDefFoundError)、链接错误(LinkageError)。这些错误是不可查的,因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况。
7.)Exception
在Exception分支中有一个重要的子类RuntimeException(运行时异常)
ArrayIndexOutOfBoundsException(数组下标越界)
NullPointerException(空指针异常)
AirthmeticException(算数异常)
MissingResourceException(丢失资源)
ClassNotFoundException(找不到类)等异常,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。
这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生;
Error和Exception的区别:Error通常是灾难性的致命错误,是程序无法控制和处理的,当出现这些异常时,Java虚拟机(JVM)一般会选择终止线程;Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常。

8.)
1 public class Test { 2 public static void main(String[] args) { 3 int a = 1; 4 int b = 0; 5 6 try{//监控区域 7 System.out.println(a/b); 8 }catch(ArithmeticException e){//catch(想要捕获的异常类型) 捕获异常 9 System.out.println("程序出现异常,变量b不能为0"); 10 }finally{//处理善后工作 11 System.out.println("finally"); 12 } 13 } 14 }
9.)要捕获多个异常,从小到大
10.)Ctrl +Alt +T 自动包裹所选中的代码
11.)throw与throws

1 public class Test { 2 public static void main(String[] args) { 3 try { 4 new Test().test(1,0); 5 } catch (ArithmeticException e) { 6 e.printStackTrace(); 7 } 8 } 9 //假设这方法中,处理不了这个异常,方法上抛出异常 throws 10 public void test(int a,int b)throws ArithmeticException{ 11 if(b==0){//throw 12 throw new ArithmeticException();//主动地抛出异常,一般在方法中使用 13 } 14 } 15 }
12.)自定义异常


1 package Demo; 2 public class MyException extends Exception{ 3 private int detail; 4 public MyException(int a){ 5 this.detail = a; 6 } 7 //toString 异常的打印信息 8 @Override //Alt + Insert 9 public String toString() { 10 return "MyException{" + "detail=" + detail + '}'; 11 } 12 static void test(int a) throws MyException{ 13 System.out.println("传递的参数为:"+a); 14 if(a>10){ 15 throw new MyException(a); 16 } 17 System.out.println("OK"); 18 } 19 public static void main(String[] args) { 20 try { 21 test(11); 22 } catch (MyException e) { 23 System.out.println("MyException=>"+e); 24 } 25 } 26 }
13.)实际应用中的经验总结

浙公网安备 33010602011771号