枚举类

一、枚举类的使用
1、枚举类的理解:类的对象只有确定的有限个。
2、当需要定义一组常量时,强烈建议使用枚举类。
3、如果枚举类中只有一个对象,则可以作为单例模式的实现方式。

二、如何定义枚举类
方式一:jdk5.0之前,自定义枚举类。
方式二:jdk5.0,可以使用enum关键字定义枚举类。

三、Enum类中的常用方法:

  • values()方法:返回枚举类型的对象数组。该方法可以很方便地遍历所有的枚举值。
  • valueOf(String str):可以把一个字符串转为对应的枚举类对象。要求字符串必须是枚举类对象的“名字”。如不是,会有运行时异常:IllegalArgumentException
  • toString():返回当前枚举类对象常量的名称。

四、使用 enum 关键字定义的枚举类实现接口的情况
情况一:实现接口,在enum类中实现抽象方法。
情况二:让枚举类的对象分别实现接口中的抽象方法。

【示例:自定义枚举类】

  1. public class SeasonTest {
  2. public static void main(String[] args) {
  3. Season spring = Season.SPRING;
  4. System.out.println(spring);//Season{seasonName='春', seasonDesc='春暖花开'}
  5. }
  6. }
  7. //自定义枚举类
  8. class Season {
  9. private final String seasonName;
  10. private final String seasonDesc;
  11. private Season(String seasonName, String seasonDesc) {
  12. this.seasonName = seasonName;
  13. this.seasonDesc = seasonDesc;
  14. }
  15. public static final Season SPRING = new Season("春", "春暖花开");
  16. public static final Season SUMMER = new Season("夏", "夏日炎炎");
  17. public static final Season AUTUMN = new Season("秋", "秋高气爽");
  18. public static final Season WINTER = new Season("冬", "冬天寒冷");
  19. public String getSeasonName() {
  20. return seasonName;
  21. }
  22. public String getSeasonDesc() {
  23. return seasonDesc;
  24. }
  25. @Override
  26. public String toString() {
  27. return "Season{" +
  28. "seasonName='" + seasonName + '\'' +
  29. ", seasonDesc='" + seasonDesc + '\'' +
  30. '}';
  31. }
  32. }

【示例:enum 关键字定义枚举类】

  1. public class SeasonTest {
  2. public static void main(String[] args) {
  3. Season spring = Season.SPRING;
  4. System.out.println(spring);//SPRING
  5. System.out.println(Season.class.getSuperclass());//class java.lang.Enum
  6. for (Season value : Season.values()) {
  7. System.out.println(value);
  8. }
  9. Season winter = Season.valueOf("WINTER");
  10. System.out.println(winter);//WINTER
  11. winter.show();//大约在冬季
  12. }
  13. }
  14. //枚举类
  15. enum Season implements Info {
  16. //1.提供当前枚举类的对象,多个对象之间用","隔开,末尾对象";"结束
  17. //每一个对象都能重写接口的方法
  18. SPRING("春", "春暖花开"){
  19. @Override
  20. public void show() {
  21. System.out.println("春天在哪里");
  22. }
  23. },
  24. SUMMER("夏", "夏日炎炎") {
  25. @Override
  26. public void show() {
  27. System.out.println("宁静的夏天");
  28. }
  29. },
  30. AUTUMN("秋", "秋高气爽"){
  31. @Override
  32. public void show() {
  33. System.out.println("秋天不回来");
  34. }
  35. },
  36. WINTER("冬", "冬天寒冷") {
  37. @Override
  38. public void show() {
  39. System.out.println("大约在冬季");
  40. }
  41. };
  42. //2.声明Season对象的属性:private final修饰
  43. private final String seasonName;
  44. private final String seasonDesc;
  45. //3.私有化类的构造器,并给对象属性赋值
  46. Season(String seasonName, String seasonDesc) {
  47. this.seasonName = seasonName;
  48. this.seasonDesc = seasonDesc;
  49. }
  50. //4.其他诉求:获取枚举类对象的属性
  51. public String getSeasonName() {
  52. return seasonName;
  53. }
  54. public String getSeasonDesc() {
  55. return seasonDesc;
  56. }
  57. }
  58. interface Info {
  59. void show();
  60. }

注解

一、理解注解(Annotation)
1、它是 jdk 5.0 新增的功能。
2、Annotation 其实就是代码里的特殊标记, 这些标记可以在编译、加载、运行时被读取, 并执行相应的处理。通过使用Annotation程序员可以在不改变原有逻辑的情况下, 在源文件中嵌入一些补充信息。
3、在JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在 JavaEE/Android 中注解占据了更重要的角色,例如用来配置应用程序的任何切面,代替 JavaEE 旧版中所遗留的繁冗代码和 XML 配置等。

二、Annotation的使用示例
1、生成文档相关的注解。
2、在编译时进行格式检查(JDK内置的三个基本注解)

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

3、跟踪代码依赖性,实现替代配置文件功能。

三、自定义注解
1、注解声明为:@interface
2、内部定义成员,通常使用 value 表示
3、可以指定成员的默认值,使用 default 定义
4、如果自定义注解没有成员,表明是一个标识作用;如果注解有成员,在使用注解时,需要指明成员的值。
5、自定义注解必须配上注解的信息处理流程(使用反射)才有意义。
6、自定义注解通过都会指明两个元注解:@Retention@Target

  1. @Inherited
  2. @Repeatable(MyAnnotations.class)
  3. @Target({TYPE, FIELD, LOCAL_VARIABLE, CONSTRUCTOR, METHOD, TYPE_PARAMETER, TYPE_USE})
  4. @Retention(RetentionPolicy.RUNTIME)
  5. public @interface MyAnnotation {
  6. String value() default "hello";
  7. }
  1. @Inherited
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Target({TYPE, FIELD, LOCAL_VARIABLE, CONSTRUCTOR, METHOD, TYPE_PARAMETER, TYPE_USE})
  4. public @interface MyAnnotations {
  5. MyAnnotation[] value();
  6. }

四、JDK 提供的4种元注解
元注解:对现有的注解进行解释说明的注解。
1、@Retention:指定所修饰的 Annotation 的生命周期:

  • RetentionPolicy.SOURCE:注解信息不会编译成字节码。
  • RetentionPolicy.CLASS(默认):注解信息会编译成字节码,但不会在运行时加载到JVM中。
  • RetentionPolicy.RUNTIME:只有声明为RUNTIME生命周期的注解,才能通过反射获取。

2、@Target:用于指定被修饰的 Annotation 能用于修饰哪些元素,比如属性、方法等。
3、@Documented:表示所修饰的注解在被javadoc解析时可以保留下来。默认情况下,javadoc是不包含注解的。定义@Documented的注解必须设置@Retention值为RUNTIME
4、@Inherited:被它修饰的 Annotation 将具有继承性。

五、JDK8 注解的新特性
1、可重复注解
MyAnnotation上声明@Repeatable,成员值为MyAnnotations.class
MyAnnotation@Target@Retention等元注解与MyAnnotations相同。

2、类型注解
ElementType.TYPE_PARAMETER 表示该注解能写在类型变量的声明语句中(如:泛型声明)。
ElementType.TYPE_USE 表示该注解能写在使用类型的任何语句中。

【示例代码】

  1. public class AnnotationTest {
  2. public static void main(String[] args) {
  3. Person p = new Student();
  4. p.walk();//学生走路上学
  5. @SuppressWarnings("unused")
  6. int num = 10;
  7. @SuppressWarnings({"unused","rawtypes"})
  8. ArrayList list = new ArrayList();
  9. }
  10. }
  11. //jdk8之前的写法:
  12. //@MyAnnotations({@MyAnnotation("hi"), @MyAnnotation("hello")})
  13. //jdk8以后的写法
  14. @MyAnnotation(value = "hi")
  15. @MyAnnotation(value = "hello")
  16. class Person{
  17. private String name;
  18. private int age;
  19. public Person() {
  20. }
  21. @MyAnnotation
  22. public Person(String name, int age) {
  23. this.name = name;
  24. this.age = age;
  25. }
  26. public String getName() {
  27. return name;
  28. }
  29. public int getAge() {
  30. return age;
  31. }
  32. public void eat(){
  33. System.out.println("人吃饭");
  34. }
  35. public void walk(){
  36. System.out.println("人走路");
  37. }
  38. }
  39. interface Info {
  40. void show();
  41. }
  42. class Student extends Person implements Info {
  43. @Override
  44. public void walk() {
  45. System.out.println("学生走路上学");
  46. }
  47. @Override
  48. public void show() {
  49. System.out.println("show");
  50. }
  51. }
  52. class Generic<@MyAnnotation T>{
  53. public void show() throws @MyAnnotation RuntimeException{
  54. ArrayList<@MyAnnotation String> list = new ArrayList<>();
  55. int num = (@MyAnnotation int) 10L;
  56. }
  57. }