01-13、JavaSE知识点总结_枚举、注解

枚举类型

  • 枚举的使用场景
    • 类的对象是有限个的,确定的
      • 星期:Monday(星期一)…Sunday(星期天)
      • 性别:Man(男)、Woman(女)
      • 季节:Spring(春节)…Winter(冬天)
    • 当需要定义一组常量时,强烈建议使用枚举类
    • 枚举类中对象外界不能创建,只能获取
    • 枚举类中只有一个对象,可以作为单例模式的一种实现方式
  • 枚举类的实现
    • JDK1.5之前需要自定义枚举类
    • JDK1.5新增enum关键字用于定义枚举类

如何自定义枚举类

class Season {
    // 对象如果有实例变量,建议声明为private final,并在构造器中初始化
    // 季节的名称
    private final String SEASONNAME;
    // 季节的描述
    private final String SEASONDESC;

    // 私有化的类构造器,保证不能在类的外部创建其对象
    private Season(String seasonName, String seasonDesc) {
        this.SEASONNAME = seasonName;
        this.SEASONDESC = seasonDesc;
    }

    //在类的内部创建枚举类的实例。声明为: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("冬天", "白雪皑皑");
}

如何使用关键字enum定义枚举类

  • 类只能使用public和默认修饰符修饰
  • 使用enum关键字定义的枚举类默认继承了java.lang.Enum类,因此不能再继承其他类,No extends clause allowed for enum
  • 枚举类的构造器只能使用private权限修饰符
  • 必须在枚举类的第一行声明所有枚举类对象,枚举项之间,逗号分隔;分号结尾,列出的实例系统会自动添加public static final修饰
  • JDK1.5中可以在switch表达式中使用Enum定义的枚举类的对象作为表达式,case子句可以直接使用枚举值的名字, 无需添加枚举类作为限定
enum SeasonEnum {

    SPRING("春天", "春风又绿江南岸"), SUMMER("夏天", "映日荷花别样红"), AUTUMN("秋天", "秋水共长天一色"), WINTER("冬天", "窗含西岭千秋雪");
    
    private final String seasonName;
    private final String seasonDesc;

	// 构造方法必须私有话
    private SeasonEnum(String seasonName, String seasonDesc) {
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }

    public String getSeasonName() {
        return seasonName;
    }
    public String getSeasonDesc() {
        return seasonDesc;
    }
}

Enum类的主要方法

方法名详细描述
public static <T extends Enum> T valueOf(Class enumType,String name)传递枚举类型的Class对象和枚举常量名称给静态方法valueOf(),会得到与参数匹配的枚举常量
public String toString()得到当前枚举常量的名称,可以重写(唯一 一个可重写的方法)这个方法得到更易读的结果
public final boolean equals(Object other)在枚举奖型中可以直接使用==来比较两个枚举常量是否相等。Enum提供的这个equals()方法,也是直接使用==实现的。它的存在是为了在Set、List 和Map中使用
public final int hashCode()Enum实现了hashCode()来和equals()保持一致
public final Class getDeclaringClass()得到枚举常量所属枚举类型的Class对象,可以用它来判断两个枚举常量是否属于同一个枚举类型
public final String name()得到当前枚举常量的名称,建议优先使用toString()
public final int ordinal()得到当前枚举常量的次序(从0开始)
public final int compareTo(E o)枚举类型实现了Comparable接口,这样可以比较两个枚举常量的大小(按照声明的顺序排列)
protected final Object clone() throws CloneNotSupportedException枚举类型不能被clone,为了防止子类实现克隆方法,Enum实现了一个仅抛出CloneNotSupponedException异常的clone()方法。Object类中clone()方法也是protected修饰的
values()返回枚举类型所有枚举值的对象数组

实现接口的枚举类

  • 和普通Java类一样,枚举类可以实现一个或多个接口
  • 若每个枚举值在调用实现的接口方法呈现相同的行为方式,则只要统一实现该方法即可
  • 若需要每个枚举值在调用实现的接口方法呈现出不同的行为方式,则可以让每个枚举值分别来实现该方法,例子参考实现枚举类型部分

实现枚举类型

第一种格式(无成员变量无抽象方法)

enum First {
    /**
     * 无成员变量无抽象方法
     */
    ZHEN, JIA;
}

第二种格式(有成员变量无抽象方法)

enum Second {
    /**
     * 有成员变量无抽象方法
     */
    MON("星期一"), TUE("星期二"), WEN("星期三");
    
    private String name;
	
	// private修饰
    Second(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

第三种格式(有成员变量有抽象方法)

enum Third {
    /**
     * 有成员变量有抽象方法
     */
    MON("星期一") {
        @Override
        public void show() {
            System.out.println("抽象方法中的星期一");
        }
    }, TUE("星期二") {
        @Override
        public void show() {
            System.out.println("抽象方法中的星期二");
        }
    }, WEN("星期三") {
        @Override
        public void show() {
            System.out.println("抽象方法中的星期三");
        }
    };
    private String name;

    Third(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public abstract void show();
}

注解

注解(Annotation)概述

  • JDK5.0开始,Java增加了Annotation(注解)的支持
  • Annotation其实就是代码里的特殊标记,这些标记可以在编译类加载运行时被读取,并执行相应的处理
  • 程序猿使用注解,可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充信息。如:代码分析工具、开发工具和部署工具,可以通过这些补充信息进行验证或者进行部署
  • 注解可用于修饰包、类、构造器、方法、成员变量、参数、局部变量的声明
  • JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等
  • JavaEE/Android中注解占据了更重要的角色,例如用来配置应用程序的任何切面,代替JavaEE旧版中所遗留的繁冗代码和XML配置等
  • 未来的开发模式都是基于注解的,JPA是基于注解的,Spring2.5以上都是基于注解的,Hibernate3.x以后也是基于注解的,现在的Struts2有一部分也是基于注解的了,注解是一种趋势,一定程度上可以说:框架=注解+反射+设计模式

常见的Annotation示例

生成API文档相关的注解

项目Value补充
@author标明开发该类模块的作者,多个作者之间使用,分割@author chenxubo
@version标明该类模块的版本@version 1.0
@see参考转向,也就是相关主题@see Math.java
@since从哪个版本开始增加的
@param对方法中某参数的说明,如果没有参数就不能写只用于方法的,可以并列多个,格式要求:@param 形参名 形参类型 形参说明
@return对方法返回值的说明,如果方法的返回值类型是void就不能写只用于方法的,格式要求:@return 返回值类型 返回值说明
@exception对方法可能抛出的异常进行说明,如果方法没有用throws显式抛出的异常就不能写只用于方法的,可以并列多个,格式要求:@exception 异常类型 异常说明

编译时进行格式检查的注解

注解Value
@Override限定重写父类方法,该注解只能用于方法
@Deprecated用于表示所修饰的元素(类、方法等)已过时。通常是因为所修饰的结构危险或存在更好的选择
@SuppressWarnings抑制编译器警告

框架中实现替代配置文件的注解

注解Value
@Transactionalspring框架中关于事务的管理
@WebServlet("/")JavaEE不再需要在web.xml文件中进行Servlet的部署

自定义Annotation

  • 定义新的Annotation类型使用@interface关键字
  • 自定义的注解自动继承了java.lang.annotation.Annotation接口
  • Annotation的成员变量在Annotation定义中以无参数方法的形式来声明,其方法名和返回值定义了该成员的名字和类型。成员变量的类型只能是八种基本数据类型、String类型、Class类型、enum类型、Annotation类型和以上所有类型的数组
  • 可以在定义Annotation的成员变量时为其指定初始值,指定成员变量的初始值可使用default关键字
  • 如果只有一个参数成员,建议参数名为value
  • 如果定义的注解含有配置参数,那么使用时必须指定参数值,除非它有默认值。格式是“参数名=参数值”,如果只有一个参数成员,且名称为value,可以省略“value=”
  • 没有成员定义的Annotation称为标记,包含成员变量的Annotation称为元数据Annotation
  • 自定义注解必须配上注解的信息处理流程才有意义
class TestTypeDefine<@TypeDefine() U> {
    private U u;

    public <@TypeDefine() T> void test(T t) {
    }
}

// @TypeDefine用于标记
@Target({ElementType.TYPE_PARAMETER})
@interface TypeDefine {
}
//@MyAnnotation(value = "chenxubo")
@MyAnnotation("chenxubo")
class MyAnnotationTest {
    public static void main(String[] args) {
        Class clazz = MyAnnotationTest.class;
        Annotation a = clazz.getAnnotation(MyAnnotation.class);
        MyAnnotation m = (MyAnnotation) a;
        String info = m.value();
        System.out.println(info);
    }
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface MyAnnotation {
    String value() default "cxb";
}

JDK中的元注解

  • JDK的元注解用于修饰其他Annotation的定义(修饰注解的注解称元注解)
  • JDK5.0提供了4个标准的元注解,分别是:
    • @Retention
    • @Target
    • @Documented
    • @Inherited

Java注解中的元注解

@Retention

  • 修饰Annotation的定义,指定该Annotation的生命周期
  • @Rentention包含一个RetentionPolicy类型的成员变量,使用@Rentention时必须为该value成员变量指定值
  • RetentionPolicy.SOURCE:在源文件中有效(源文件保留,编译器直接丢弃这种策略的注释)
  • RetentionPolicy.CLASS:在class文件中有效(字节码文件中保留,当运行Java程序时,JVM不会保留注解)
  • RetentionPolicy.RUNTIME:在运行时有效(运行时保留,当运行Java程序时,JVM会保留注解,程序可以通过反射获取该注解)
  • RetentionPolicy.SOURCE和RetentionPolicy.CLASS策略下获取注解的值抛出java.lang.NullPointerException

@Target

  • 修饰Annotation的定义,用于指定被修饰的Annotation能用于修饰哪些程序元素
  • @Target包含了一个名为value的ElementType[]类型的成员变量

@Documented

  • @Documented修饰的Annotation将被javadoc工具提取成文档,默认情况下javadoc是不包括注解的

@Inherited

  • @Inherited修饰的Annotation将具有继承性。如果某个类使用了被@Inherited修饰的Annotation, 则其子类将自动具有该注解
  • 把标有@Inherited注解的自定义的注解标注在类级别上,子类则可以继承父类类级别的注解

利用反射获取注解信息(在反射部分涉及)

  • 利用反射获取注解信息需要修饰注解的@Retention元注解取值为RUNTIME,也就是必须被虚拟机保留
  • 当@Retention注解的取值不是RUNTIME的时候,就不能通过反射来获取注解信息了,但是可以使用javac来处理注解
  • JDK5.0在java.lang.reflect包下新增了AnnotatedElement接口,AnnotatedElement代表在当前运行的JVM中一个可以被注解的元素,这个接口允许通过反射读取元素上面的注解
限定词解释
directly present元素上显式声明的注解
indrectly present可重复注解和包含注解类型的情况
present在directly present基础上增加了继承的情况
associated在directly present和indrectly的基础上增加了继承的情况
  • 限定词作用:AnnotatedElement中的方法都是根据这些限定词来返回注解的,也就是说,不同的方法可能返回不同限定词指定的注解
方法Directly PresentIndirectly PresentPresentAssociated
T getAnnotation(Class)
Annotation[] getAnnotations
T[] getAnnotationsByType(Class)
T getDeclaredAnnotation(Class annotationClass)
T[] getDeclaredAnnotationsByType(Class annotationClass)
Annotation[] getDeclaredAnnotations()
import java.lang.annotation.*;
import java.util.Arrays;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface DirectlyPresent {
    int id();
    String description() default "this is a common description";
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Repeatable(IndirectlyPresent.class)
@interface IndirectlyPresentValue {
    String name();
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface IndirectlyPresent {
    IndirectlyPresentValue[] value();
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@interface InheritablePresent {
}

@InheritablePresent()
class ParentPresentElement {
}

@DirectlyPresent(id = 2, description = "this is a DirectlyPresentElement")
@IndirectlyPresent({@IndirectlyPresentValue(name = "firstName")})
public class PresentElement extends ParentPresentElement {
    public static void main(String[] args) {
        Class<PresentElement> directlyPresentElementClass = PresentElement.class;

        // Directly Present的注解有
        Annotation[] declaredAnnotations = directlyPresentElementClass.getDeclaredAnnotations();
        // [@DirectlyPresent(description=this is a DirectlyPresentElement, id=2), @IndirectlyPresent(value=[@IndirectlyPresentValue(name=firstName)])]
        System.out.println(Arrays.toString(declaredAnnotations));


        // Indirectly Present的注解有
        DirectlyPresent[] declaredAnnotationsByType1 = directlyPresentElementClass.getDeclaredAnnotationsByType(DirectlyPresent.class);
        // [@DirectlyPresent(description=this is a DirectlyPresentElement, id=2)]
        System.out.println(Arrays.toString(declaredAnnotationsByType1));
        IndirectlyPresent[] declaredAnnotationsByType2 = directlyPresentElementClass.getDeclaredAnnotationsByType(IndirectlyPresent.class);
        // [@IndirectlyPresent(value=[@IndirectlyPresentValue(name=firstName)])]
        System.out.println(Arrays.toString(declaredAnnotationsByType2));
        IndirectlyPresentValue[] declaredAnnotationsByType3 = directlyPresentElementClass.getDeclaredAnnotationsByType(IndirectlyPresentValue.class);
        // [@IndirectlyPresentValue(name=firstName)]
        System.out.println(Arrays.toString(declaredAnnotationsByType3));


        // Present注解有
        Annotation[] annotations = directlyPresentElementClass.getAnnotations();
        // [@InheritablePresent(), @DirectlyPresent(description=this is a DirectlyPresentElement, id=2), @IndirectlyPresent(value=[@IndirectlyPresentValue(name=firstName)])]
        System.out.println(Arrays.toString(annotations));
        
        
        // Associated注解有
    }
}

JDK8中注解的新特性

  • Java8对注解处理提供了两点改进:可重复注解及类型注解
  • Java8以前,同一个程序元素前最多只能有一个相同类型的注解,Java8新增了重复注解@Repeatable
  • Java8以前,注解只能用在各种程序元素(定义类、定义接口、定义方法、定义成员变量…)上,Java8开始,类型注解可以用在任何使用到类型的地方
  • Java8关于元注解@Target的参数类型ElementType枚举值多了两个:TYPE_PARAMETER、TYPE_USE
    • ElementType.TYPE_PARAMETER:表示该注解能写在类型参数的声明语句中。类型参数声明如: <T>、<T extends Person>
    • ElementType.TYPE_USE:表示注解可以在任何用到类型的地方使用,比如创建对象、类型转换、使用implements实现接口、使用throws声明抛出异常
@MyAnnotation
class AnnotationTest<U> {
    @MyAnnotation
    private String name;

    public static void main(String[] args) {
        AnnotationTest<@MyAnnotation String> t = null;
        int a = (@MyAnnotation int) 2L;
        @MyAnnotation
        int b = 10;
    }
    public static <@MyAnnotation T> void method(T t) {
    }
    public static void test(@MyAnnotation String arg) throws @MyAnnotation Exception {
    }
}

@Target(ElementType.TYPE_USE)
@interface MyAnnotation {
}

JDK8新特性|重复注解与类型注解

注解使用时注意点

  • 注解中属性只有一个并且为value时可以省略属性名,直接写属性值
  • 注解中属性给默认值,使用时可以不给该属性赋值
  • 注解中属性的类型只能是八种基本数据类型、String类型、Class类型、enum类型、Annotation类型和以上所有类型的数组,数组只有一个元素大括号可以不写
@interface MyAnnotation {
    //属性名  
    String name();

    int age() default 10;

    String value();

    boolean[] is();
}

class MyAnnotationTest {

    @MyAnnotation(name = "aaa", value = "bbb", is = true)
    public static void m1() {
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值