zoukankan      html  css  js  c++  java
  • Java反射(2)访问字段(Field)

    目录:
    1.访问字段(Field)对象的方法汇总
    2.获取字段(Field)对象中的值
    3.设置字段(Filed)对象中的值

    1.访问Field的方法汇总

    以下四种方法在Class类可以返回关于字段的 Field 对象。

    Field[] getFields()   // 返回所有可访问的公共字段,在类中声明或继承自父类。
    Field[] getDeclaredFields()  //获取当前类的所有field(不包括父类)
    Field getField(String name)  //根据字段名获取某个public的field(包括父类)
    Field getDeclaredField(String name)  //根据字段名获取当前类的某个field(不包括父类)
    

    Field是一个类。对于我们想研究的某个字段(比如自定义的Student类的字段id),对应着Filed类的一个对象。

    • Filed类中定义的主要属性如下:
    public final class Field extends AccessibleObject implements Member {
    
        private Class<?>            clazz;//
        private int                 slot;
        private String              name;
        private Class<?>            type;//
        private int                 modifiers;//修饰符
        private transient String    signature;
        private transient FieldRepository genericInfo;
        private byte[]              annotations;
        private FieldAccessor fieldAccessor;
        private FieldAccessor overrideFieldAccessor;
    ......
    }
    
    class Student {
        public int id;
        private int studentName;
    }
    
    • Filed的部分访问方法:
            Field field=Student.class.getField("score");
            System.out.println(field.getClass());//class java.lang.reflect.Field
            System.out.println(field.getName());//score
            System.out.println(field.getType());//int
            int modifier=field.getModifiers();
            System.out.println(Modifier.isFinal(modifier));//false
            System.out.println(Modifier.isPublic(modifier));//true
    

    2.获取Field中的值

    • 获取公有字段的值
    • 获取私有字段的值
    
    import java.lang.reflect.Field;
    import java.lang.reflect.Modifier;
    
    public class ErasedTypeTest {
        public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
            Student student=new Student("Zhangsan");
            Field f1=Student.class.getField("name");
            System.out.println(f1.get(student));//获取Field对象中的public字段的值
    
            Field f2=Student.class.getDeclaredField("grade");
            f2.setAccessible(true);//①不加这行代码   ②加这行
            System.out.println(f2.get(student));//获取Field对象中的私有字段的值   
            // ①IllegalAccessException    ② 0
        }
    
    }
    class Student  {
        public String name;
        private int grade;
        public Student(String name) {
            this.name = name;
        }
    }
    

    可能有人回问:如果使用反射可以获取private字段的值,那么类的封装还有什么意义?

    答案是:正常情况下,我们总是通过student.name来访问Student的name字段,编译器会根据public、protected和private决定是否允许访问字段,这样就达到了数据封装的目的。

    而反射是一种非常规的用法,使用反射,首先代码非常繁琐,其次,它更多地是给工具或者底层框架来使用,目的是在不知道目标实例任何信息的情况下,获取特定字段的值。

    此外,setAccessible(true)可能会失败。如果JVM运行期存在SecurityManager,那么它会根据规则进行检查,有可能阻止setAccessible(true)。例如,某个SecurityManager可能不允许对java和javax开头的package的类调用setAccessible(true),这样可以保证JVM核心库的安全。

    设置字段中的值

    set与get类似

            f2.setAccessible(true);
            f2.set(student,10000);
            System.out.println(f2.get(student));//10000
    
  • 相关阅读:
    sun.misc.BASE64Encoder找不到jar包的解决方法
    mybatis中的#和$的区别
    mysql , oracle 从记录中查询出 楼盘下只有 no 公司的 楼盘
    Windows+Git+TortoiseGit+COPSSH 安装 教程
    oracle job 定时执行 存储过程
    如何在PL/SQL中修改ORACLE的字段顺序
    oracle创建数据库连接dblink
    oracle数据库去掉重复记录;只保留一条数据
    Oracle中like查询下划线等特殊字符的处理
    START WITH CONNECT BY PRIOR子句实现递归查询
  • 原文地址:https://www.cnblogs.com/JohnTeslaaa/p/12716571.html
Copyright © 2011-2022 走看看