Java自学笔记(枚举注解)

枚举

  • 枚举的本质:继承了Enum抽象类的类

  • 枚举是一种引用类型,枚举是一个规定了取值范围的数据类型

  • 枚举变量不能使用其他的数据,只能使用枚举中常量赋值,提高程序安全性

  • 定义枚举使用enum关键字

  • 枚举的本质

    • 枚举是一个终止类,并且继承Enum抽象类

    • 枚举中常量是当前类型的静态常量

  • 枚举注意事项

    • 1 枚举中主要包括静态常量(只写常量名),常量之间使用逗号隔开,最后分号可写可不写(如果后面有代码,必须写分号)

    • 2.枚举也可以包含私有的构造方法,属性,方法,但是必须写在常量的后面

  • 使用场景

    • 使用在switch中

    • package com.qf.day25;
      ​
      public enum Weak {
          周一,周二,周三,周四,周五,周末;
      }
      package com.qf.day25;
      ​
      public class TestWeak {
          public static void main(String[] args) {
              Weak weak = Weak.周一;
              switch(weak){
                  case 周一:
                      System.out.println("小莲花");
                      break;
                  case 周二:
                      System.out.println("小翠");
                      break;
                  case 周三:
                      System.out.println("小蜘蛛");
                      break;
                  case 周五:
                      System.out.println("小蒙");
                      break;
                  case 周末:
                      System.out.println("睡觉");
                      break;
                  default:
                      System.out.println("输入错误");
              }
          }
      }
    • 枚举实现单例

      package com.qf.day25;
      ​
      public enum SingleTon {
          INSTANCE;
      }
      package com.qf.day25;
      ​
      public class Test {
          public static void main(String[] args) {
              SingleTon singleTon1 = SingleTon.INSTANCE;
              SingleTon singleTon2 = SingleTon.INSTANCE;
              SingleTon singleTon3 = SingleTon.INSTANCE;
              System.out.println(singleTon1.hashCode());   //1929600551
              System.out.println(singleTon2.hashCode());   //1929600551
              System.out.println(singleTon3.hashCode());   //1929600551
              System.out.println("-------------------------------");
              System.out.println(singleTon1.toString());   //INSTANCE
          }
      }
  • /**
     * 枚举注意事项
     *    1 枚举中主要包括静态常量(只写常量名),常量之间使用逗号隔开,最后分号可写可不写(如果后面有代码,必须写分号)
     *    2.枚举也可以包含私有的构造方法,属性,方法,但是必须写在常量的后面
     */
    public enum Gender {
        男,
        女;
        private Gender(){
    ​
        }
        private  int value;
    }
    package com.qf.day25;
    ​
    public class TestStudent {
        public static void main(String[] args) {
            Student s1 = new Student("小莲花",21,Gender.女);
            System.out.println(s1.toString());
        }
    }
    package com.qf.day25;
    ​
    public class Student {
        private String name;
        private int age;
        private Gender sex;
    }

注解

  • 注解(Annotation)是代码里的特殊标记,程序可以读取注解,一般用于代替配置文件

  • 开发人员可以通过注解告诉类如何运行

    • 在Java技术里注解的典型应用是:可以同过反射技术去得到类里的注解,以决定怎么去运行类

  • 常见注解:

    • @Override:表示一个方法声明打算重写超类中的另一个方法声明

    • @Deprecated:用来注解程序元素,不鼓励程序员使用这样的元素,通常是因为他很危险或存在更好的选择(表示类已过时,向其他程序员传递已过时信息,有更好的选择)

  • 定义注解使用@interface关键字,注解中只能包含属性

  • 注解属性类型:

    • String类型

    • 基本数据类型

    • Class类型

    • 枚举类型

    • 注解类型

    • 以上类型的一维数组

  • 在注解中可以定义属性,以下是@MyAnnotation注解中的name属性。如果一个注解中有属性,在使用时必须为属性赋值。否则报错.如果有多个属性,必须为每个属性赋值,中间使用“,”隔开----->@MyAnnotation (属性名=属性值 , 属性名=属性值 ->name = "小莲花",age = 18)

    • String name( ) ;

    • 可以为注解中的属性赋予默认值:int age () default 20//给age属性赋予20默认值 如果不使用默认值,也可以为属性赋值

    • 当注解的属性只有一个,并且属性名是 value 时, 使用注解时可以省略value ,直接赋值

    • @MyAnnotation ( "小莲花")

元注解

  • 用来描述注解的注解

  • @Retention:用于指定注解可以保留的域(被修饰的注解在编译后的保存位置)

    • RetentionPolicy.CLASS:

      • 注解记录在class文件中,运行Java程序是,JVM不会保留,此为默认值

    • RetenPolicy.RUNTIME

      • 注解记录在class文件中,运行Java程序是,JVM会保留,程序可以通过反射获取该注解

    • RetenPolicy.SOURCE

      • 编译时直接丢弃这种策略的注解

    • package com.qf.day25_1;
      ​
      import java.lang.reflect.Method;
      ​
      public class Person {
      ​
          @MyAnnotation(name = "小莲花",age = 20)
          public void show() throws Exception{
              //通过反射获取注解的属性
              //1.获取类对象
              Class c1 = Class.forName("com.qf.day25_1.Person");
              //获取类方法
              Method method = c1.getMethod("show");
              //获取方法上的注解
              MyAnnotation my  = method.getAnnotation(MyAnnotation.class);
              //通过注解获取属性
              System.out.println("注解的属性以及属性值:"+my.name());  //Exception in thread "main" java.lang.NullPointerException
                                                                   //没有使用元注解,将注解设置为可以被反射获取
                //注解的属性以及属性值:小莲花:20
          }
      }
      package com.qf.day25_1;
      ​
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      ​
      /**
       * 使用@interface定义一个注解
       *   1.注解中只能包含属性,属性名后面需要加小括号
       */
      //设置该注解可以被反射获取,在编译时保存在jvm中
      @Retention(RetentionPolicy.RUNTIME)
      public @interface MyAnnotation {
          String name();
          int age();
      }
  • @Target:

    • 指定注解用于修饰类的那个成员。用来标注“注解”的注解,注解用来标注“被标注的注解”可以出现在哪些位置上

    • 例如:@Target(ElementType.METHOD),表示被Target修饰的注解只能出现在方法上。

public class ReflectMyAnnotation {
    public static void main(String[] args) throws Exception{
        //获取类
        Class c = Class.forName("com.qf.day0620.TestMyAnnotation");
        //判断类上面是否有@MyAnntation
        //System.out.println(c.isAnnotationPresent(MyAnnotion.class));  //true
        if(c.isAnnotationPresent(MyAnnotion.class)){  //RetentionPolicy.RUNTIME
            //获取注解对象
            MyAnnotion m = (MyAnnotion)c.getAnnotation(MyAnnotion.class);
            System.out.println("该类上的注解是:"+m);  //该类上的注解是:@com.qf.day0620.MyAnnotion()
            //获取注解对象的属性
            String value = m.value();
            System.out.println("注解中的属性:"+value);  //注解中的属性:小莲花
            // 注解中的属性:小翠(此时在调用MyAnnotion时,对value赋予默认值)

            //如果想获取方法上注解的信息,首先通过反射获取Class类,然后通过反射方法获取方法,最后使用isAnnotationPresent和getAnnotation
                        //获取属性,当属性有多个时,通过反射的注解.属性名即可获取
        }
 }
/**
 * 定义注解,只能在类、方法上使用
 */
@Target({ElementType.TYPE,ElementType.METHOD})
//希望这个注解可以被反射
@Retention(RetentionPolicy.RUNTIME)
public @interface  MyAnnotion {
    String value() default "小莲花";
​
}
package com.qf.day0620;
@MyAnnotion("小翠")
public class TestMyAnnotation {
   // @MyAnnotion
    private int i;
    public void doSome(){
        System.out.println("doSome......");
    }
}

注解在开发过程中的使用

  • 注解在程序中等同于一种标记,如果这个元素上有这个注解一应该怎么办,没有这个注解怎么办

  • 需求

    • 假设有一个注解,注解名 : @Id

    • 此注解只能出现在在类上面。当这个类上有这个注解时,要求这个类中必须有一个int类型的id属性。如果没有属性就报异常,如果有这个属性则正常执行。

    • 注解类

    • package com.qf.day0620_1;
      ​
      import java.lang.annotation.ElementType;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      import java.lang.annotation.Target;
      ​
      /**
       * 此注解只能出现在类上方
       */
      @Target({ElementType.TYPE})
      //表示该注解可以被反射机制读取到
      @Retention(RetentionPolicy.RUNTIME)
      public @interface Id {
      }
    • 学生类

    • package com.qf.day0620_1;
      ​
      @Id
      public class Student {
          private String name;
          private int id;
          private int age;
      }
    • 自定义异常类

    • package com.qf.day0620_1;
      ​
      public class AnnotationException extends RuntimeException{
      ​
          public AnnotationException() {
          }
      ​
          public AnnotationException(String message) {
              super(message);
          }
      }
    • 测试类

    • package com.qf.day0620_1;
      import java.lang.reflect.Field;
      public class TestId {
          public static void main(String[] args) throws Exception{
              //获取类
              Class student = Class.forName("com.qf.day0620_1.Student");
              //判断类上方是否使用@Id修饰
              System.out.println(student.isAnnotationPresent(Id.class));
              if(student.isAnnotationPresent(Id.class)){  //如果存在
                  //创建Boolean类型数据,判断是否按照规定定义
                  boolean b = false;
                  //获取类中的全部属性
                  Field[] fields = student.getDeclaredFields();
                  for(Field f:fields){  //遍历属性,判断是否含有Id属性,以及Id属性的类型是否是int
                      if("id".equals(f.getName())&&"int".equals(f.getType().getSimpleName())){
                          b = true;
                          break;
                      }
                  }
                  //判断是否合法
                  if(!b){
                      throw new  AnnotationException("使用@Id修饰的类,其属性中必须包含id(int)属性");
                  }else{
                      System.out.println("恭喜正确使用了@Id注解");
                  }
              }
          }
      }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值