Class -- 09 -- Field类常用方法解析

原文链接:Class – 09 – Field类常用方法解析


相关文章:


这次主要整理下 Java 中 Field 类的常用方法


一、Field 类的定义

  • Field 类位于 java.lang.reflect 包中,主要用于在程序运行状态中,动态地获取或设置字段信息

二、Field 类常用方法

  • getAnnotatedType()

    • 返回一个 AnnotatedType 对象,该对象表示使用类型来指定由该字段对象表示的字段的类型

    • 通过其 getType() 方法,我们可以获取到对应的字段类型

      public class FieldTest {
      
          private String name;
      
          public static void main(String[] args) throws Exception {
              Field field = FieldTest.class.getDeclaredField("name");
              AnnotatedType annotatedType = field.getAnnotatedType();
              // class java.lang.String
              System.out.println(annotatedType.getType());
          }
      }
      

  • getAnnotation(Class<T> annotationClass)

    • 如果该字段对象存在指定类型的注解,则返回该注解,否则返回 null

    • 只有类级别的注解会被继承得到,对于其他对象而言,getAnnotation() 方法与 getDeclaredAnnotation() 方法作用相同

      @Target(ElementType.FIELD)
      @Retention(RetentionPolicy.RUNTIME)
      public @interface FieldAnnotation {
      
          String key();
      
          String value();
      }
      
      public class FieldTest {
      
          @FieldAnnotation(key = "key", value = "value")
          private String name;
      
          public static void main(String[] args) throws Exception {
              Field field = FieldTest.class.getDeclaredField("name");
              FieldAnnotation annotation = field.getAnnotation(FieldAnnotation.class);
              // @lang.reflect.FieldAnnotation(key=key, value=value)
              System.out.println(annotation);
          }
      }
      

  • getDeclaredAnnotation(Class<T> annotationClass)

    • 如果该字段对象存在指定类型的注解,则返回该注解,否则返回 null

    • 只有类级别的注解会被继承得到,对于其他对象而言,getAnnotation() 方法与 getDeclaredAnnotation() 方法作用相同


  • getAnnotationsByType(Class<T> annotationClass)

    • 如果该字段对象存在指定类型的注解,则返回该注解数组,否则返回 null

    • 只有类级别的注解会被继承得到,对于其他对象而言,getAnnotationsByType() 方法与 getDeclaredAnnotationsByType() 方法作用相同

    • getAnnotationsByType() 方法与 getAnnotation() 方法的区别在于:getAnnotationsByType() 方法会检查修饰该字段对象的注解是否为可重复类型注解,如果是则会返回修饰该字段对象的一个或多个注解

    • @Repeatable 用于声明注解为可重复类型注解

    • 当声明为可重复类型注解后,如果字段注解仍为一个,则 getAnnotation() 方法会正常返回,如果字段注解为多个,则 getAnnotation() 方法会返回 null

      @Target(ElementType.FIELD)
      @Retention(RetentionPolicy.RUNTIME)
      @Repeatable(RepeatableAnnotation.class)
      public @interface FieldAnnotation {
      
          String key();
      
          String value();
      }
      
      @Target(ElementType.FIELD)
      @Retention(RetentionPolicy.RUNTIME)
      @interface RepeatableAnnotation {
      
          FieldAnnotation[] value();
      }
      
      public class FieldTest {
      
          @FieldAnnotation(key = "key1", value = "value1")
          @FieldAnnotation(key = "key2", value = "value2")
          private String name;
      
          public static void main(String[] args) throws Exception {
              Field field = FieldTest.class.getDeclaredField("name");
              // null
              System.out.println(field.getAnnotation(FieldAnnotation.class));
              FieldAnnotation[] annotationsByType = field.getAnnotationsByType(FieldAnnotation.class);
              // [@com.xj.FieldAnnotation(key=key1, value=value1), @com.xj.FieldAnnotation(key=key2, value=value2)]
              System.out.println(Arrays.toString(annotationsByType));
          }
      }
      

  • getDeclaredAnnotationsByType(Class<T> annotationClass)

    • 如果该字段对象存在指定类型的注解,则返回该注解数组,否则返回 null

    • 只有类级别的注解会被继承得到,对于其他对象而言,getAnnotationsByType() 方法与 getDeclaredAnnotationsByType() 方法作用相同


  • getAnnotations()

    • 返回该字段对象上的所有注解,如果没有注解,则返回空数组

    • 只有类级别的注解会被继承得到,对于其他对象而言,getAnnotations() 方法与 getDeclaredAnnotations() 方法作用相同

      @Target(ElementType.FIELD)
      @Retention(RetentionPolicy.RUNTIME)
      public @interface FieldAnnotation {
      
          String key();
      
          String value();
      }
      
      @Target(ElementType.FIELD)
      @Retention(RetentionPolicy.RUNTIME)
      public @interface TestAnnotation {
      
          String key();
      
          String value();
      }
      
      public class FieldTest {
      
          @FieldAnnotation(key = "key1", value = "value1")
          @TestAnnotation(key = "key2", value = "value2")
          private String name;
      
          public static void main(String[] args) throws Exception {
              Field field = FieldTest.class.getDeclaredField("name");
              Annotation[] annotations = field.getAnnotations();
              // [@lang.reflect.FieldAnnotation(key=key1, value=value1), @lang.reflect.TestAnnotation(key=key2, value=value2)]
              System.out.println(Arrays.toString(annotations));
          }
      }
      

  • getDeclaredAnnotations()

    • 返回该字段对象上的所有注解,如果没有注解,则返回空数组

    • 只有类级别的注解会被继承得到,对于其他对象而言,getAnnotations() 方法与 getDeclaredAnnotations() 方法作用相同


  • getModifiers()

    • 返回修饰该字段对象修饰符的整数形式,使用 Modifier 类对其进行解码

      public class FieldTest {
      
          private String name;
      
          public static void main(String[] args) throws Exception {
              Field field = FieldTest.class.getDeclaredField("name");
              // private
              System.out.println(Modifier.toString(field.getModifiers()));
          }
      }
      

  • getName()

    • 返回字段对象名称

      public class FieldTest {
      
          private String name;
      
          public static void main(String[] args) throws Exception {
              Field field = FieldTest.class.getDeclaredField("name");
              // name
              System.out.println(field.getName());
          }
      }
      

  • getType()

    • 返回一个 Class 对象,该 Class 对象表示该字段对象表示的声明字段的类型 (擦除泛型)

      public class FieldTest<T> {
      
          private T name;
      
          public static void main(String[] args) throws Exception {
              Field field = FieldTest.class.getDeclaredField("name");
              // class java.lang.Object
              System.out.println(field.getType());
          }
      }
      

  • getGenericType()

    • 返回一个 Type 对象,该 Type 对象表示该字段对象表示的声明字段的类型 (保留泛型)

      public class FieldTest<T> {
      
          private T name;
      
          public static void main(String[] args) throws Exception {
              Field field = FieldTest.class.getDeclaredField("name");
              // T
              System.out.println(field.getGenericType());
          }
      }
      

  • isAnnotationPresent(Class<? extends Annotation> annotationClass)

    • 如果该字段对象上有指定类型的注解,则返回 true,否则为 false

      public class FieldTest {
      
          @FieldAnnotation(key = "key", value = "value")
          private String name;
      
          public static void main(String[] args) throws Exception {
              Field field = FieldTest.class.getDeclaredField("name");
              // true
              System.out.println(field.isAnnotationPresent(FieldAnnotation.class));
          }
      }
      

  • getDeclaringClass()

    • 返回该字段对象表示的字段所在类的 Class 对象

      public class FieldTest {
      
          private String name;
      
          public static void main(String[] args) throws Exception {
              Field field = FieldTest.class.getDeclaredField("name");
              Class<?> declaringClass = field.getDeclaringClass();
              // class lang.reflect.FieldTest
              System.out.println(declaringClass);
          }
      }
      

  • isEnumConstant()

    • 如果该字段对象表示枚举类型的元素,则返回 true,否则返回 false

      public class FieldTest {
      
          private String name;
      
          public static void main(String[] args) throws Exception {
              Field field = FieldTest.class.getDeclaredField("name");
              // false
              System.out.println(field.isEnumConstant());
          }
      }
      

  • toString()

    • 返回该字段对象的字符串表示形式 (擦除泛型)

      public class FieldTest<T> {
      
          private T name;
      
          public static void main(String[] args) throws Exception {
              Field field = FieldTest.class.getDeclaredField("name");
              // private java.lang.Object lang.reflect.FieldTest.name
              System.out.println(field.toString());
          }
      }
      

  • toGenericString()

    • 返回该字段对象的字符串表示形式 (保留泛型)

      public class FieldTest<T> {
      
          private T name;
      
          public static void main(String[] args) throws Exception {
              Field field = FieldTest.class.getDeclaredField("name");
              // private T lang.reflect.FieldTest.name
              System.out.println(field.toGenericString());
          }
      }
      

  • isSynthetic()

    • 如果该字段对象为合成字段,则返回 true,否则为 false

    • 编译器在编译的时候,会在内部类中生成一个字段,该字段指向一个外部类的实例

      public class FieldTest {
      
          private String name;
      
          private class InnerClass {
          
          }
      
          public static void main(String[] args) throws Exception {
              InnerClass innerClass = new FieldTest().new InnerClass();
              Field[] fields = innerClass.getClass().getDeclaredFields();
              for (Field field : fields) {
                  // 【final lang.reflect.FieldTest lang.reflect.FieldTest$InnerClass.this$0】 isSynthetic(): true
                  System.out.println("【" + field + "】" + " isSynthetic(): " + field.isSynthetic());
              }
          }
      }
      
    • InnerClass 内部类反编译得到如下结果,生成了一个 this$0 的字段

      class FieldTest$InnerClass {
          private FieldTest$InnerClass(FieldTest var1) {
              this.this$0 = var1;
          }
      }
      
    • 有关 synthetic 的相关内容,小伙伴可以看下这里


  • isAccessible()

    • 获取该字段对象的可访问标志

      public class FieldTest {
      
          private String name;
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      }
      
      public class Test {
      
          public static void main(String[] args) throws Exception {
              FieldTest fieldTest = new FieldTest();
              fieldTest.setName("小明");
              Field[] declaredFields = FieldTest.class.getDeclaredFields();
              for (Field declaredField : declaredFields) {
                  // false
                  System.out.println(declaredField.isAccessible());
              }
          }
      }
      

  • setAccessible(boolean flag)

    • 设置该字段对象的可访问标志

    • 在其他类里获取该类的私有成员变量时,需要设置访问标志为 true,否则会报异常

      public class FieldTest {
      
          private String name;
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      }
      
      public class Test {
      
          public static void main(String[] args) throws Exception {
              FieldTest fieldTest = new FieldTest();
              fieldTest.setName("小明");
              Field[] declaredFields = FieldTest.class.getDeclaredFields();
              for (Field declaredField : declaredFields) {
                  declaredField.setAccessible(true);
                  // 小明
                  System.out.println(declaredField.get(fieldTest));
              }
          }
      }
      

  • getChar(Object obj)

    • 获取 char 类型的静态或实例字段的值,或通过扩展转换将另一个基本数据类型转换为 char 类型的值

  • getByte(Object obj)

    • 获取 byte 类型的静态或实例字段的值,或通过扩展转换将另一个基本数据类型转换为 byte 类型的值

  • getShort(Object obj)

    • 获取 short 类型的静态或实例字段的值,或通过扩展转换将另一个基本数据类型转换为 short 类型的值

  • getInt(Object obj)

    • 获取 int 类型的静态或实例字段的值,或通过扩展转换将另一个基本数据类型转换为 int 类型的值

  • getLong(Object obj)

    • 获取 long 类型的静态或实例字段的值,或通过扩展转换将另一个基本数据类型转换为 long 类型的值

  • getFloat(Object obj)

    • 获取 float 类型的静态或实例字段的值,或通过扩展转换将另一个基本数据类型转换为 float 类型的值

  • getDouble(Object obj)

    • 获取 double 类型的静态或实例字段的值,或通过扩展转换将另一个基本数据类型转换为 double 类型的值

  • getBoolean(Object obj)

    • 获取 boolean 类型的静态或实例字段的值,或通过扩展转换将另一个基本数据类型转换为 boolean 类型的值

  • getBoolean(Object obj)

    • 获取 Object 类型的静态或实例字段的值,如果是基本数据类型,则会将该值将自动包装在对象中

public class FieldTest {

    private char charField = 'A';
    private byte byteField = 110;
    private short shortField = 111;
    private int intField = 112;
    private long longField = 113;
    private float floatField = 1.23F;
    private double doubleField = 1.23;
    private boolean booleanField = true;
    private Object objField = "哈哈哈";

    public static void main(String[] args) throws Exception {
        Class<FieldTest> fieldTestClass = FieldTest.class;
        /**
         * 获取char类型的静态或实例字段的值,或通过扩展转换将另一个基本数据类型转换为char类型的值
         */
        Field charField = fieldTestClass.getDeclaredField("charField");
        FieldTest charFieldTest = new FieldTest();
        System.out.println(charField.getChar(charFieldTest)); // A
        charField.setChar(charFieldTest, 'B');
        System.out.println(charField.getChar(charFieldTest)); // B

        /**
         * 获取byte类型的静态或实例字段的值,或通过扩展转换将另一个基本数据类型转换为byte类型的值
         */
        Field byteField = fieldTestClass.getDeclaredField("byteField");
        FieldTest byteFieldTest = new FieldTest();
        System.out.println(byteField.getByte(byteFieldTest)); // 110
        byteField.setByte(byteFieldTest, (byte) 120);
        System.out.println(byteField.getByte(byteFieldTest)); // 120

        /**
         * 获取short类型的静态或实例字段的值,或通过扩展转换将另一个基本数据类型转换为short类型的值
         */
        Field shortField = fieldTestClass.getDeclaredField("shortField");
        FieldTest shortFieldTest = new FieldTest();
        System.out.println(shortField.getShort(shortFieldTest)); // 111
        shortField.setShort(shortFieldTest, (short) 888);
        System.out.println(shortField.getShort(shortFieldTest)); // 888

        /**
         * 获取int类型的静态或实例字段的值,或通过扩展转换将另一个基本数据类型转换为int类型的值
         */
        Field intField = fieldTestClass.getDeclaredField("intField");
        FieldTest intFieldTest = new FieldTest();
        System.out.println(intField.getInt(intFieldTest)); // 112
        intField.setInt(intFieldTest, 888);
        System.out.println(intField.getInt(intFieldTest)); // 888

        /**
         * 获取long类型的静态或实例字段的值,或通过扩展转换将另一个基本数据类型转换为long类型的值
         */
        Field longField = fieldTestClass.getDeclaredField("longField");
        FieldTest longFieldTest = new FieldTest();
        System.out.println(longField.getLong(longFieldTest)); // 113
        longField.setLong(longFieldTest, 888L);
        System.out.println(longField.getLong(longFieldTest)); // 888

        /**
         * 获取float类型的静态或实例字段的值,或通过扩展转换将另一个基本数据类型转换为float类型的值
         */
        Field floatField = fieldTestClass.getDeclaredField("floatField");
        FieldTest floatFieldTest = new FieldTest();
        System.out.println(floatField.getFloat(floatFieldTest)); // 1.23
        floatField.setFloat(floatFieldTest, 1.88F);
        System.out.println(floatField.getFloat(floatFieldTest)); // 1.88

        /**
         * 获取double类型的静态或实例字段的值,或通过扩展转换将另一个基本数据类型转换为double类型的值
         */
        Field doubleField = fieldTestClass.getDeclaredField("doubleField");
        FieldTest doubleFieldTest = new FieldTest();
        System.out.println(doubleField.getDouble(doubleFieldTest)); // 1.23
        doubleField.setDouble(doubleFieldTest, 1.88);
        System.out.println(doubleField.getDouble(doubleFieldTest)); // 1.88

        /**
         * 获取boolean类型的静态或实例字段的值,或通过扩展转换将另一个基本数据类型转换为boolean类型的值
         */
        Field booleanField = fieldTestClass.getDeclaredField("booleanField");
        FieldTest booleanFieldTest = new FieldTest();
        System.out.println(booleanField.getBoolean(booleanFieldTest)); // true
        booleanField.setBoolean(booleanFieldTest, false);
        System.out.println(booleanField.getBoolean(booleanFieldTest)); // false

        /**
         * 获取Object类型的静态或实例字段的值,如果是基本数据类型,则会将该值将自动包装在对象中
         */
        Field objField = fieldTestClass.getDeclaredField("objField");
        FieldTest objFieldTest = new FieldTest();
        System.out.println(objField.get(objFieldTest)); // 哈哈哈
        objField.set(objFieldTest, "啊啊啊");
        System.out.println(objField.get(objFieldTest)); // 啊啊啊
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值