枚举、注解与反射学习笔记

枚举、注解与反射学习笔记

一、枚举

  • 格式
    权限修饰符 enum 枚举名称 {
    实例1,实例2,实例3,实例4;
    }
  • 简介
    JDK1.5引入了新的类型——枚举。在JDK1.5 之前,我们定义常量都是: public static fianl… 。很难管理。
    枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。用于定义有限数量的一组同类常量,例如:
    错误级别:
    低、中、高、急
    一年的四季:
    春、夏、秋、冬
    商品的类型:
    美妆、手机、电脑、男装、女装…
    在枚举类型中定义的常量是该枚举类型的实例。
public class Level2 {
    //1.5版本之前的枚举
    public static final Level2 LOW = new Level2(1);
    public static final Level2 MIDIUM = new Level2(3);
    public static final Level2 HIGH = new Level2(5);
    private int value;

    private Level2(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
}
public enum Level {
    //1.5版本后格式1
   LOW(1),MIDIUM(3),HIGH(5) ;
    private Level(int value) {
        this.value = value;
    }
    private int value;

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
}
//1.5版本后格式2
public enum Level1 {
     LOW,MIDIUM,HIGH;
}

最后一种为最常用的方式,枚举值默认为从0开始的有序数值。以 Level1枚举类型举例,它的枚举常量依次为 LOW:0,MIDIUM:1,HIGH:2

  • Enum抽象类常见方法Enum抽象类常见方法

  • 枚举类使用注意事项

    • 一旦定义了枚举,最好不要妄图修改里面的值,除非修改是必要的。
    • 枚举类默认继承的是java.lang.Enum类而不是Object类
    • 枚举类不能有子类,因为其枚举类默认被final修饰 只能有private构造方法 switch中使用枚举时,直接使用常量名,不用携带类名
    • 不能定义name属性,因为自带name属性
    • 不要为枚举类中的属性提供set方法,不符合枚举最初设计初衷。

    二、注解

    • 简介

      • Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。
      • Java 语言中的类、方法、变量、参数和包等都可以被标注。和注释不同,Java 标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。当然它也支持自定义 Java 标注。
      • 主要用于:
        • 编译格式检查
        • 反射中解析
        • 生成帮助文档
        • 跟踪代码依赖 等
    • 内置注解

      • @Override : 重写
        • 定义在java.lang.Override
      • @Deprecated:废弃
        • 定义在java.lang.Deprecated
      • @SafeVarargs
        • Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。
      • @FunctionalInterface: 函数式接口 *
        • Java 8 开始支持,标识一个匿名函数或函数式接口。
      • @Repeatable:标识某注解可以在同一个声明上使用多次
        • Java 8 开始支持,标识某注解可以在同一个声明上使用多次
      • SuppressWarnings:抑制编译时的警告信息。
        • 定义在java.lang.SuppressWarnings
        • 三种使用方式
1. @SuppressWarnings("unchecked") [^ 抑制单类型的警告]
2. @SuppressWarnings("unchecked","rawtypes") [^ 抑制多类型的警告]
3. @SuppressWarnings("all") [^ 抑制所有类型的警告]
  • 元注解 :作用在其他注解的注解

    • @Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
    • @Documented - 标记这些注解是否包含在用户文档中 javadoc。
    • @Target - 标记这个注解应该是哪种 Java 成员。
    • @Inherited - 标记这个注解是自动继承的
  • 自定义注解

    • 格式:@interface 自定义注解名{}
    • 注意事项
    1. 定义的注解,自动继承了java.lang,annotation.Annotation接口
    2. 注解中的每一个方法,实际是声明的注解配置参数,方法的名称就是 配置参数的名称
      方法的返回值类型,就是配置参数的类型。只能是:基本类型/Class/String/enum
    3. 可以通过default来声明参数的默认值
    4. 如果只有一个参数成员,一般参数名为value
    5. 注解元素必须要有值,我们定义注解元素时,经常使用空字符串、0作为默认值。
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation1 {
参数类型 参数名() default 默认值;
}

三、反射

JAVA反射机制是在运行状态中,获取任意一个类的结构 , 创建对象 , 得到方法,执行方法 , 属性 ;这种在运行状态动态获取信息以及动态调用对象方法的功能被称为java语言的反射机制。

1.所有类型的Class对象

在Java中,每一个字节码文件,被加载到内存后,都存在一个对应的Class类型的对象。

2.得到Class的三种方式

  • 如果在编写代码时, 指导类的名称, 且类已经存在, 可以通过包名.类名.class 得到一个类的 类对象。
  • 如果拥有类的对象, 可以通过Class 对象.getClass() 得到一个类的 类对象。
  • 如果在编写代码时, 知道类的名称 , 可以通过Class.forName(包名+类名): 得到一个类的 类对象。

上述的三种方式, 在调用时, 如果类在内存中不存在, 则会加载到内存 ! 如果类已经在内存中存在, 不会重复加载, 而是重复利用 !
特殊的类对象

  • 基本数据类型的类对象:
    基本数据类型.class
    包装类.type
  • 基本数据类型包装类对象:
    包装类.class

3.获取Constructor以及使用

Class<Person> pclass = (Class<Person>) Class.forName("com.java.demo.Person");
        //获取无参的构造方法
        Constructor<Person> c = pclass.getConstructor();
        //获取有参的构造方法
        Constructor<Person> c1 = pclass.getConstructor(String.class,int.class);
        //获取私有权限的构造方法,getDeclaredConstructor获取所有权限的构造方法
        Constructor<Person> c2 = pclass.getDeclaredConstructor(String.class);
        //使用无参构造方法创建对象
        Person p = c.newInstance();
        //使用有参构造方法创建对象,需要传参。
        Person p1 = c1.newInstance("name",18);
        //使用私有权限的构造方法创建对象,需要先忽略权限检查。
        c2.setAccessible(true);
        Person p2 = c2.newInstance("name");

4.获取Method以及使用

  1. getMethod(String methodName , class… clss)
    根据参数列表的类型和方法名, 得到一个方法(public修饰的)
  2. getMethods();
    得到一个类的所有方法 (public修饰的)
  3. getDeclaredMethod(String methodName , class… clss)
    根据参数列表的类型和方法名, 得到一个方法(除继承以外所有的:包含私有, 共有, 保护, 默认)
  4. getDeclaredMethods();
    得到一个类的所有方法 (除继承以外所有的:包含私有, 共有, 保护, 默认)
  5. invoke(Object o,Object… para) :
    调用方法 ,
    参数1. 要调用方法的对象
    参数2. 要传递的参数列表
  6. getName()
    获取方法的方法名称
  7. setAccessible(boolean flag)
    如果flag为true 则表示忽略访问权限检查 !(可以访问任何权限的方法)

5.获取Field以及使用

  1. getField(属性名);getDeclaredField(属性名)
  2. set(Object o , Object value);
    参数1. 要设置属性值的 对象
    参数2. 要设置的值,设置指定对象的属性的值
  3. getName():获取属性的名称
  4. setAccessible(boolean flag)
    如果flag为true 则表示忽略访问权限检查 !(可以访问任何权限的属性)

6.获取获取注解信息

.1、获取类/属性/方法的全部注解对象

Annotation[] annotations01 = Class/Field/Method.getAnnotations();
for (Annotation annotation : annotations01) {
System.out.println(annotation);
}

2、根据类型获取类/属性/方法的注解对象

注解类型 对象名 = (注解类型) c.getAnnotation(注解类型.class);
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值