枚举类与注解


一、作业

代码阅读题:

public class ReturnExceptionDemo {
	static void methodA() {
		try {
			System.out.println("进入方法A");
			throw new RuntimeException("制造异常");
		} finally {
			System.out.println("用A方法的finally");
		}
	}

	static void methodB() {
		try {
			System.out.println("进入方法B");
			return;
		} finally {
			System.out.println("调用B方法的finally");
		}
	}

	public static void main(String[] args) {
		try {
			methodA();
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		
		methodB();
	}
}

答案:

进入方法A
用A方法的finally
制造异常
进入方法B
调用B方法的finally

编程题:

	编写应用程序EcmDef.java,接收命令行的两个参数,要求不能输入负数,计算两数相除。
	对数据类型不一致(NumberFormatException)、缺少命令行参数(ArrayIndexOutOfBoundsException、
  	除0(ArithmeticException)及输入负数(EcDef 自定义的异常)进行异常处理。
	提示: 
	(1)在主类(EcmDef)中定义异常方法(ecm)完成两数相除功能。
	(2)在main()方法中使用异常处理语句进行异常处理。
	(3)在程序中,自定义对应输入负数的异常类(EcDef)。
	(4)运行时接受参数 java EcmDef 20 10   //args[0]=“20” args[1]=“10”
	(5)Interger类的static方法parseInt(String s)将s转换成对应的int值。
        如:int a=Interger.parseInt(“314”);	//a=314;

答案:

/**
 * @ClassName: EcDef
 * @Description: 自定义输入负数的异常类
 * @author Ralph
 * @date 2020年3月6日 下午10:33:28
 *
 */
class EcDef extends Exception {
	static final long serialVersionUID = -3387519931240229948L;

	
	public EcDef() {
		super();
	}

	public EcDef(String message) {
		super(message);
	}
}
public class EcmDef {

	/**
	 * 
	 * @Description 使用异常语句处理异常
	 * @author shkstart
	 * @date 2020年3月7日上午9:01:21
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			
			int i = Integer.parseInt(args[0]);
			int j = Integer.parseInt(args[1]);
			int result = ecm(i,j);
			
			System.out.println("运算结果为:" + result);
		} catch (NumberFormatException e) {
			System.out.println("数据类型不一致");
		} catch (EcDef e) {
			System.out.println(e.getMessage());
		} catch (ArithmeticException e) {
			System.out.println("除0");
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("缺少命令行参数");
		}
	}

	/**
	 * 
	 * @Description 定义异常方法完成两数相处功能
	 * @author shkstart
	 * @date 2020年3月7日上午9:01:35
	 * @param args
	 * @param args2
	 * @throws EcDef 
	 */
	public static int ecm(int i, int j) throws EcDef {
		
		if(i < 0 || j < 0){
			throw new EcDef("输入的数为负数了");
		}
		
		return i / j;
		
	}
}

二、复习

  • 异常的体系结构
    • java.lang.Throwable
      • java.lang.Error:错误,不编写针对性的代码进行处理。StackOverflowError,OutOfMemoryError
      • java.lang.Exception:异常。需要考虑进行处理的。
  • 常见的异常类:编译时异常(checked) vs 运行时异常(RuntimeException)
  • 异常处理的方式一:try-catch-finally
  • 异常处理的方式二:throws + 异常类型1,异常类型2
  • 除了代码中自动生成异常对象之外,我们还可以手动创建一个异常对象,并手动throw出去。
  • 用户自定义异常类

三、枚举类

1. 理解

 * 1. 枚举类的理解:类的对象只有有限个,确定的。则此类可以看做是枚举类。
 * 
 * 2. 举例:
 * 星期:Monday(星期一)、......、Sunday(星期天)
 * 性别:Man(男)、Woman(女)
 * 季节:Spring(春节)......Winter(冬天)
 * 支付方式:Cash(现金)、WeChatPay(微信)、Alipay(支付宝)、BankCard(银行卡)、CreditCard(信用卡)
 * 就职状态:Busy、Free、Vocation、Dimission
 * 订单状态:Nonpayment(未付款)、Paid(已付款)、Delivered(已发货)、Return(退货)、Checked(已确认)Fulfilled(已配货)
 * 线程状态:创建、就绪、运行、阻塞、死亡
 * 
 * 3. 当需要定义一组常量时,强烈建议使用枚举类
 * 4. 如果枚举类的对象只有一个,则枚举类可以看做单例模式的实现方式。

2. 如何自定义枚举类

public class SeasonTest {
	public static void main(String[] args) {
		Season summer = Season.SUMMER;
		System.out.println(summer);
		System.out.println(summer.getSEASON_NAME());
		
	}
}

//自定义枚举类
class Season{
	
	//1. 声明每个对象拥有的属性:private final修饰
	private final String SEASON_NAME;
	private final String SEASON_DESC;
	
	//2. 私有化类的构造器
	private Season(String seasonName,String seasonDesc){
		this.SEASON_NAME = seasonName;
		this.SEASON_DESC = seasonDesc;
	}
	
	//3. 创建枚举类中的对象:public static final 
	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("冬天","白雪皑皑");
	
	//4. 提供toString()
	@Override
	public String toString() {
		return "Season [SEASON_NAME=" + SEASON_NAME + ", SEASON_DESC=" + SEASON_DESC + "]";
	}

	public String getSEASON_NAME() {
		return SEASON_NAME;
	}

	public String getSEASON_DESC() {
		return SEASON_DESC;
	}
	
	
}

3. 使用enum关键字定义枚举类

//使用enum关键字定义枚举类
enum Season1 implements Info{
	//1. 创建枚举类中的对象,声明在enum枚举类的首位
	SPRING("春天","春暖花开"),
	SUMMER("夏天","夏日炎炎"),
	AUTUMN("秋天","秋高气爽"),
	WINTER("冬天","白雪皑皑");
	
	//2. 声明每个对象拥有的属性:private final修饰
	private final String SEASON_NAME;
	private final String SEASON_DESC;
	
	//3. 私有化类的构造器
	private Season1(String seasonName,String seasonDesc){
		this.SEASON_NAME = seasonName;
		this.SEASON_DESC = seasonDesc;
	}
	

	public String getSEASON_NAME() {
		return SEASON_NAME;
	}

	public String getSEASON_DESC() {
		return SEASON_DESC;
	}


	@Override
	public void show() {
		System.out.println("这是一个美好的季节!");
	}
	
	
}

4. java.lang.Enum类中的常用方法

 * 		toString():返回当前枚举类对象的对象名
 * 		values():返回当前枚举类中所有对象构成的数组
 * 		valueOf(String name):返回指定name名称的枚举类的对象
public class SeasonTest1 {
	public static void main(String[] args) {
		Season1 summer = Season1.SUMMER;
		//toString():返回当前枚举类对象的对象名
		System.out.println(summer.toString());
		
		System.out.println(Season1.class.getSuperclass());//class java.lang.Enum
		
		
		//values():返回当前枚举类中所有对象构成的数组
		Season1[] seasons = Season1.values();
		for(int i = 0;i < seasons.length;i++){
			System.out.println(seasons[i]);
			seasons[i].show();
		}
		
		//valueOf(String name):返回指定name名称的枚举类的对象
		String name = "AUTUMN";
		Season1 s1 = Season1.valueOf(name);
		System.out.println(s1);//AUTUMN
		
		name = "AUTUMN1";
		//如果枚举类中不存在指定名称的枚举类对象,则报java.lang.IllegalArgumentException。
//		Season1 s2 = Season1.valueOf(name);
//		System.out.println(s2);
		
	}
}

5. 枚举类实现接口中的方法

interface Info{
	void show();
}

//使用enum关键字定义枚举类
enum Season1 implements Info{
	//1. 创建枚举类中的对象,声明在enum枚举类的首位
	SPRING("春天","春暖花开"){
		public void show(){
			System.out.println("春天在哪里?");
		}
	},
	SUMMER("夏天","夏日炎炎"){
		public void show(){
			System.out.println("宁静的夏天");
		}
	},
	AUTUMN("秋天","秋高气爽"){
		public void show(){
			System.out.println("秋天是用来分手的季节");
		}
	},
	WINTER("冬天","白雪皑皑"){
		public void show(){
			System.out.println("2002年的第一场雪");
		}
	};
	
	//2. 声明每个对象拥有的属性:private final修饰
	private final String SEASON_NAME;
	private final String SEASON_DESC;
	
	//3. 私有化类的构造器
	private Season1(String seasonName,String seasonDesc){
		this.SEASON_NAME = seasonName;
		this.SEASON_DESC = seasonDesc;
	}
	

	public String getSEASON_NAME() {
		return SEASON_NAME;
	}

	public String getSEASON_DESC() {
		return SEASON_DESC;
	}

	
}

四、注解(Annotation)

1. 注解的理解

 * 1. Annotation,是jdk5.0新增的特性
 * 2. 理解:
 * Annotation 其实就是代码里的特殊标记, 这些标记可以在编译, 类加载, 运行时被读取, 
 * 并执行相应的处理。通过使用 Annotation, 程序员可以在不改变原有逻辑的情况下, 在源文件
 * 中嵌入一些补充信息。

2. 注解的应用举例

   示例一:生成文档相关的注解
 * 	@author 标明开发该类模块的作者,多个作者之间使用,分割
 *  @version 标明该类模块的版本
 *  @see 参考转向,也就是相关主题
 *  @since 从哪个版本开始增加的
 * 
 * 示例二:在编译时进行格式检查(JDK内置的三个基本注解)
 * @Override: 限定重写父类方法, 该注解只能用于方法
 * @Deprecated: 用于表示所修饰的元素(类, 方法等)已过时。通常是因为所修饰的结构危险或存在更好的选择
 * @SuppressWarnings: 抑制编译器警告
 * 
 * 示例三:跟踪代码依赖性,实现替代配置文件功能

3. java基础阶段常见的三个注解

 * 	@Override: 限定重写父类方法, 该注解只能用于方法
 *  @Deprecated: 用于表示所修饰的元素(类, 方法等)已过时。通常是因为所修饰的结构危险或存在更好的选择
 *  			 标识为过时的结构,虽然还可以在程序中使用,但是不建议使用。
 *  @SuppressWarnings: 抑制编译器警告
public class AnnotationTest {
	
	public static void main(String[] args) {
		Person p = new Student();
		p.walk();
		
		@SuppressWarnings("deprecation")
		Date date = new Date(2020 - 1900,3 - 1,4);
		System.out.println(date);//Wed Mar 04 00:00:00 GMT+08:00 2020
		
		p.eat();
		
		@SuppressWarnings("unused")
		int num = 10;
//		System.out.println(num);
		
		@SuppressWarnings({ "rawtypes", "unused" })
		List list = new ArrayList();
	}
}


class Person{
	@Deprecated
	public void eat(){
		System.out.println("人吃饭");
	}
	public void walk(){
		System.out.println("人走路");
	}
	
}

class Student extends Person{
	
	@Override
	public void walk() {
		super.walk();
	}
}

4. 如何自定义注解

如何自定义注解(了解)
 * 		参照@SuppressWarnings定义
 * 	   ① 使用@interface来声明
 *     ② 内部可以声明属性,属性类型限于:八种基本数据类型、String类型、Class类型、enum类型、Annotation类型、以上所有类型的数组
 *     ③ 如果注解内部不定义任何属性,则称为标识注解
 *     ④ 属性可以声明默认值,使用default定义
 * 
 *   说明:要想自定义的注解在使用在相关结构的位置上起作用,必须结合后面的反射。通过反射获取相应的注解及注解上的属性的值,进行必要的操作。
 * 
public @interface MyAnnotation {
	String value() default "atguigu";
}

使用自定义的注解:

@MyAnnotation
class Person{
	
	@Deprecated
	public void eat(){
		System.out.println("人吃饭");
	}
	
	@MyAnnotation(value="hello")
	public void walk(){
		System.out.println("人走路");
	
	
}

5. 元注解

用于修饰现有注解的注解,就称为元注解

  • Retention:用于指定该 Annotation 的生命周期

    • SOURCE:编译不保留 ; CLASS(默认行为):编译保留,运行不保留;RUNTIME:编译保留,运行也保留
  • Target:用于指定被修饰的 Annotation 能用于修饰哪些程序元素。

    在这里插入图片描述

  • Documented:用于指定被该元 Annotation 修饰的 Annotation 类将被 javadoc 工具提取成文档

  • Inherited:被它修饰的 Annotation 将具有继承性。

    说明:一般注解都会提供两个元注解: @Retention,@Target。

举例:

import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MyAnnotation {
	String value() default "atguigu";
}
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    String[] value();
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

在这里插入图片描述

6. 如何通过反射获取注解的信息(放到反射章节再讲)

​ 前提:要求当前注解的生命周期为:RUNTIME

7. jdk8注解新特性(了解)

  • 重复注解

    import static java.lang.annotation.ElementType.CONSTRUCTOR;
    import static java.lang.annotation.ElementType.FIELD;
    import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
    import static java.lang.annotation.ElementType.METHOD;
    import static java.lang.annotation.ElementType.PARAMETER;
    import static java.lang.annotation.ElementType.TYPE;
    
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotations {
    	MyAnnotation[] value();
    }
    
    @Repeatable(MyAnnotations.class)
    @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotation {
    	String value() default "atguigu";
    }
    
    
    //旧的写法
    //@MyAnnotations({@MyAnnotation,@MyAnnotation(value="abc")})
    //新的写法
    @MyAnnotation(value="abc")
    @MyAnnotation
    class Person{
    }
    
  • 类型注解

    在Target的属性可以赋值为:

在这里插入图片描述
修改MyAnntation可以修饰的结构:

@Repeatable(MyAnnotations.class)
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE,TYPE_PARAMETER,TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
	String value() default "atguigu";
}

测试:

public class AnnotationTest {
	
	public <@MyAnnotation T> void method(T t){
		
		int a  = (@MyAnnotation int)2L;
	}
}

tation(value=“abc”)})
//新的写法
@MyAnnotation(value=“abc”)
@MyAnnotation
class Person{
}


- 类型注解

在Target的属性可以赋值为:

[外链图片转存中...(img-lWND1x6B-1584063460332)]

修改MyAnntation可以修饰的结构:

```java
@Repeatable(MyAnnotations.class)
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE,TYPE_PARAMETER,TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
  String value() default "atguigu";
}

测试:

public class AnnotationTest {
	
	public <@MyAnnotation T> void method(T t){
		
		int a  = (@MyAnnotation int)2L;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值