1.枚举与版本
枚举自JDK1.5版本后开始有
1.5以前则用private final String 定义属性
和private来私有化构造器
public static final 来创建对象
并用Get方法获取
枚举类:类的对象的个数是可数多个(有限)的 这样的类我们叫作枚举类。
JDK1.5开始有枚举类
*/
/*
JDK1.5之前的枚举类如何实现
*/
class Season{
//属性 - 每个对象各自拥有一份。
private final String NAME;
private final String INFO;
//私有化构造器-不能在类的外面创建该类的对象
private Season(String name,String info){
this.NAME = name;
this.INFO = info;
}
//创建对象
public static final Season SPRING = new Season("春天","春暖花开"); //常量
public static final Season SUMMER = new Season("夏天","夏天蚊子咬");
public static final Season AUTUMN = new Season("秋天","秋天有落叶");
public static final Season WINTER = new Season("冬天","冬天穿棉袄");
public String getNAME() {
return NAME;
}
public String getINFO() {
return INFO;
}
}
public class EnumTest {
public static void main(String[] args) {
//获取Season对象
Season spring = Season.SPRING;
System.out.println(spring.getNAME() + " " + spring.getINFO());
}
}
1.5版本后
格式 : 权限修饰符 enum 枚举类的名字{
}
权限修饰符:只能用public 和缺省的 和类的修饰符相同
枚举类默认继承了java.lang.Enum类
枚举类的构造器只能用private 修饰 默认用private 修饰
枚举中自定义用final 修饰 因为对象都是常量 所以不需要用static过度修饰
switch -case中变量类型可以是枚举类型
switch中可用类型 byte int short char 字符串 枚举
/*
JDK1.5之后的枚举类如何实现
格式 : 权限修饰符 enum 枚举类的名字{
}
权限修饰符 :只能是public和缺省的。
说明:
1.枚举类不能再继承其它类。因为默认继承了java.lang.Enum类
2.创建对象 - 枚举类中声明的对象必须放在类中的首行。多个对象之间用","分隔开最后用“;”结尾
3.枚举类的构造器默认是private修饰也只能是private修饰
4.如果我们要在枚举类中自定义属性 那么建议该属性用final修饰(因为对象都是常量 所以对象中的属性也要常量但不要被static修饰)。
5.switch-case中 switch中的变量的类型可以是枚举类型。
*/
enum Season3{
SPRING,SUMMER,AUTUMN,WINTER;
}
class A{
public void test(){
//switch (byte,short,int,字符串,char,枚举)
switch (Season3.SPRING){
case AUTUMN:
break;
case SPRING:
break;
}
}
}
//枚举类不能再继承其它类。因为默认继承了java.lang.Enum类
enum Season2{
//创建对象 - 枚举类中声明的对象必须放在类中的首行。多个对象之间用","分隔开最后用“;”结尾
SPRING("春天"),SUMMER("夏天"), AUTUMN("秋天"), WINTER("冬天");
private final String name; //final修饰的变量必须赋值
//枚举类的构造器 -只能是private
//private Season2(){}//默认是private
private Season2(String name){ //自定义了一个有参的构造器
this.name = name;
} //默认是private
public String getName() {
return name;
}
}
public class EnumTest2 {
public static void main(String[] args) {
}
}
2.枚举类使用场景
1.类比较少
2.形参限定 只能使用枚举,避免范围为的随意传参
class State{
public static final int OPEN = 0;
public static final int CLOSE = 1;
}
/*
在类的设计中 如果是关于某些状态一般用枚举类(比较少)
在类的设计中 如果是关于某些参数(比较多)(比如: ip地址 端口号 线程数量 ....... 等后面Kafka就知道了)
*/
enum ComputerState{
OPEN,CLOSE;//对象
}
public class EnumTest3 {
public static void main(String[] args) {
//setComputerState(-5);
setComputerState(ComputerState.OPEN);
}
/*
用枚举类作为方法的形参的好处就是只能传枚举类中的某一个对象。
*/
public static void setComputerState(ComputerState state){
if (state == ComputerState.CLOSE){
}else{
}
}
//设置电脑的状态
// public static void setComputerState(int state){
//
// }
}
3.枚举类中的API
了解即可
/*
枚举类中的方法
*/
import java.util.Arrays;
public class EnumAPITest {
/*
下面了解即可
1.String toString(): 默认返回的是常量名(对象名),可以继续手动重写该方法!
2.String name():返回的是常量名(对象名)
3.int ordinal():返回常量的次序号,默认从0开始
4.枚举类型[] values():返回该枚举类的所有的常量对象,返回类型是当前枚举的数组类型,是一个静态方法
5.枚举类型 valueOf(String name):根据枚举常量对象名称获取枚举对象
*/
public static void main(String[] args) {
//枚举类型[] values():返回该枚举类的所有的常量对象,返回类型是当前枚举的数组类型,是一个静态方法
Season2[] values = Season2.values();
System.out.println(Arrays.toString(values));
//枚举类型 valueOf(String name):根据枚举常量对象名称获取枚举对象
Season2 spring = Season2.valueOf("SPRING");//实参是个字符串 - 严格区分大小写
System.out.println(spring.getName());
//String toString(): 默认返回的是常量名(对象名),可以继续手动重写该方法!
String string = Season2.SPRING.toString();
System.out.println(string);
//String name():返回的是常量名(对象名)
System.out.println(Season2.SPRING.getName());
//int ordinal():返回常量的次序号,默认从0开始
System.out.println(Season2.SPRING.ordinal());
}
}
4.异常概述及异常演示
异常的结构 throwable 总表异常
Error 表示严重错误 无法用catch进行处理修复
Exception :可以catch到进行处理的普通异常 分为编译时异常和运行时异常
编译时异常:在程序编译时发生的异常,不一定会发生 但有发生的风险
运行时异常:程序运行时的代码错误导致(空指针 下角标越界等错误)
/*
异常 : 指的是在程序运行的过程中,出现非正常的情况导致程序终止
注意:异常不是指的语法错误或逻辑代码错误
JVM(系统)是如何处理异常的
Java中把不同的异常用不同的类表示。一旦发生某种异常。系统就会创建对应异常类的对象并抛出。
该异常是可以被catch到如果catch到后可以做相应的处理。如果没有catch动作程序终止运行。
异常体系结构:
|------Throwable
|-------Error: 表示严重错误。无法catch只能程序挂掉。
|-------Exception :表示普通异常是可以被catch到的。catch到后可以做相应的处理程序不会挂掉。没有catch到程序一样终止运行。
|------编译时异常(受检异常):在程序编译的时候发生的异常-不一定会真正的发生异常只是有可能会发生异常
例:有一个程序该程序需要读取配置文件,但该配置文件有可能找不到不是说一定找不到。
那这个读取文件的操作(方法)就会在编译时发生异常-所以需要处理该异常-万一找不到了怎么办。
|------运行时异常(非受检异常)(RuntimeException及子类):在程序运行的时候发生的异常。
这类异常是由程序员的代码编写错误导致(比如:空指针 下角标越界 类型转换异常)
*/
public class ExceptionTest {
public static void main(String[] args) {
//error演示
//error();
runtimeException();
}
/*
非受检异常:运行时异常
*/
public static void runtimeException(){
//System.out.println(1 / 0);//ArithmeticException
//NullPointerException
// String s = null;
// System.out.println(s.length());
//ClassCastException
// Object o = new Integer("1");//多态
// String s = (String) o;
//ArrayIndexOutOfBoundsException
// int[] ns = new int[2];
// ns[3] = 10;
}
/*
编译时异常
*/
public static void exception(){
//受检异常-编译时异常
//FileNotFoundException
//new FileInputStream("a.txt");
//InterruptedException
//Thread.sleep(10000);
}
public static void error(){
/*
演示 error : OutOfMemoryError
*/
//int[] n = new int[Integer.MAX_VALUE];//Integer.MAX_VALUE int的最大值
//StackOverflowError
error();
}
}
5.try —— catch ——finally 结构
格式
try{
可能发生错误的代码
}catch(异常类型1){
}...
finally{
一定要执行的代码
}
无论什么情况finally中代码一定会执行 除了还没执行就结束
/*
我们提到的异常指的是Exception
处理异常:
方式一 :try-catch-finally
方式二 :throws
处理异常方式一:try-catch-finally
格式:
try{
可能会发生异常的代码
代码1
代码2 --> 发生异常。代码3就不再执行了
代码3
}catch(异常类型1){
异常类型1的处理
}catch(异常类型2){
异常类型2的处理
}
.......
finally{
一定要执行的代码
}
说明:
1.如果try中的代码没有发生异常 那么会执行完try中所有的代码后跳到finally中执行finally中的代码。
然后跳出try-catch-finally结果继续向下执行其它代码
2.如果try中的代码发生了异常 那么在try中发生异常的代码后面的try中代码不再执行。
系统会根据相应的异常创建异常类的对象并抛出。因为我们会catch异常所以会和catch后面的异常类型匹配。
如果和第一个catch后面的异常类型匹配失败继承向下匹配直到匹配成功并执行相应catch中的代码执行完后
跳到finally中并执行finally中的代码执行完后跳出try-catch-finally并继续向下执行其它代码。
如果向下匹配失败那么会进入finally中执行finally中的代码然后终止程序的运行(因为没抓到异常-没有匹配成功)。
3.注意:finally可以省略不写 ,如果有finally无论什么情况finally中的代码一定会执行。
*/
public class ExceptionTest2 {
public static void main(String[] args) {
demo4();
}
/*
没有finally
*/
public static void demo4(){
try{
System.out.println("开始执行代码");
System.out.println(1 / 0);
System.out.println("执行完代码");
}catch (ClassCastException e){
System.out.println("类型转化异常");
}catch (NullPointerException e){
System.out.println("空指针异常");
}
System.out.println("over");
System.out.println("over");
}
/*
有异常但没有catch到
*/
public static void demo3(){
try{
System.out.println("开始执行代码");
System.out.println(1 / 0);
System.out.println("执行完代码");
}catch (ClassCastException e){
System.out.println("类型转化异常");
}catch (NullPointerException e){
System.out.println("空指针异常");
}finally {
System.out.println("劳资一定要执行");
}
System.out.println("over");
System.out.println("over");
}
//没有异常
public static void demo2(){
try{
System.out.println("开始执行代码");
//System.out.println(1 / 0);
System.out.println("执行完代码");
}catch (ClassCastException e){
System.out.println("类型转化异常");
}catch (NullPointerException e){
System.out.println("空指针异常");
}catch (ArithmeticException e){
System.out.println("算术运算异常");
}finally {
System.out.println("劳资一定要执行");
}
System.out.println("over");
System.out.println("over");
}
public static void demo1(){
try{
System.out.println("开始执行代码");
System.out.println(1 / 0);
System.out.println("执行完代码");
}catch (ClassCastException e){
System.out.println("类型转化异常");
}catch (NullPointerException e){
System.out.println("空指针异常");
}catch (ArithmeticException e){
System.out.println("算术运算异常");
}finally {
System.out.println("劳资一定要执行");
}
System.out.println("over");
System.out.println("over");
}
}
6.try —— catch ——finally再说明
catch作用时收集异常信息
异常写父类 : tongyichul
异常类型写具体类型 : 不同类型不同处理最后写父类
catch可以省略
finally 作用:关闭资源 保存某些数据 保存某些状态
public class ExceptionTest3 {
public static void main(String[] args) {
demo3();
}
public static void demo3(){
try {
new FileInputStream("a.txt");//编译时异常 - 必须处理。不处理没办法运行。
} catch (FileNotFoundException e) {
//实际生产中-要收集异常信息
System.out.println(e.getMessage());//getMessage() : 获取异常信息 -- 将异常信息写到日志文件
e.printStackTrace();//将异常信息打印到控制台
}
System.out.println("over");
System.out.println("over");
}
/*
异常的类型写父类还是具体的类型呢?
场景1(异常类型写父类) : 无论什么异常全部是统一处理方式
场景2(异常类型要写具体的类型 最后用父类兜底) :不同的异常不同的处理方法
注意:如果要匹配多种异常类型 小的(异常的子类)在前面大的(异常的父类)在后面。
*/
public static void demo2(){
try{
System.out.println("开始执行代码");
//System.out.println(1 / 0); //运行时异常
String s = null;
System.out.println(s.length());//运行时异常
System.out.println("执行完代码");
}catch (ArithmeticException e){ // 写父类
System.out.println("处理方式1");
}catch (NullPointerException e){ // 写父类
System.out.println("处理方式2");
}catch (Exception e){ // 写父类
System.out.println("统一处理");
}
System.out.println("over");
System.out.println("over");
}
/*
如何catch到所有异常
*/
public static void demo1(){
try{
System.out.println("开始执行代码");
//System.out.println(1 / 0);
String s = null;
System.out.println(s.length());
System.out.println("执行完代码");
}catch (Exception e){ // 写父类
System.out.println("发生异常了");
}
System.out.println("over");
System.out.println("over");
}
}
/*
catch可以省略 :try-finally结构
*/
public class ExceptionTest4 {
public static void main(String[] args) {
demo1();
}
public static void demo1(){
/*
try-catch : 有异常要处理 没有一定要执行的代码
try-catch-finally : 有异常要处理 而且有一定要执行的代码(比如 ①关闭资源 ②保存某些数据 ③保存某些状态)
try-finally : 有异常不处理 有一定要执行的代码(比如 ①关闭资源 ②保存某些数据 ③保存某些状态)
*/
try {
System.out.println(1 / 0);
}finally {
//finally中放的是一定要执行的代码
//场景 :比如 ①关闭资源 ②保存某些数据 ③保存某些状态
System.out.println("我一定要执行");
}
System.out.println("over");
}
}
7.jdk1.7的结构再变化
/*
在jdk1.7的时候 catch中的写法可以这么写 :catch(异常的类型 | 异常的类型2 e)
*/
public class ExceptionTest5 {
public static void main(String[] args) {
try{
System.out.println(1 / 0);
}catch (NullPointerException | ArithmeticException e){
System.out.println("发生异常了");
}
}
}
9.finally不执行的情况
/*
finally : finally中的代码一定会执行(除非System.exit(0) 关闭JVM).
1.就算在try-catch中有return finally中的代码也一定要执行
2.如果finally中出现return那么try-catch中的return就失效了 -- (其实发生覆盖)
*/
public class FinallyTest {
public static void main(String[] args) {
// System.out.println(demo1());
// System.out.println(demo2());
demo3();
}
/*
finally不会执行的情况
*/
public static void demo3(){
try{
System.exit(0); //关闭JVM --- System.exit(0) :0是JVM退出的状态码。0是正常退出
}catch (Exception e){
System.out.println("发生了异常");
}finally {
System.out.println("finally一定会执行");
}
}
/*
就算在try-catch中发生了return,那么finally中的return仍然会执行。
*/
public static int demo2(){
try{
return 1;
}catch (Exception e){
return 2;
}finally {
return 3; //如果finally中出现return那么try-catch中的return就失效了 -- (其实发生覆盖)
}
}
/*
就算在try-catch中有return finally中的代码也一定要执行
*/
public static int demo1(){
try{
return 1;
}catch (Exception e){
return 2;
}finally {
System.out.println("finally中的代码一定要执行");
}
}
}