首页 > 编程语言 >java访问字段

java访问字段

时间:2022-10-22 11:06:34浏览次数:48  
标签:Field java 获取 private 访问 字段 实例 public

对任意的一个​​Object​​​实例,只要我们获取了它的​​Class​​,就可以获取它的一切信息。

我们先看看如何通过​​Class​​实例获取字段信息。​​Class​​类提供了以下几个方法来获取字段:

  • Field getField(name):根据字段名获取某个public的field(包括父类)
  • Field getDeclaredField(name):根据字段名获取当前类的某个field(不包括父类)
  • Field[] getFields():获取所有public的field(包括父类)
  • Field[] getDeclaredFields():获取当前类的所有field(不包括父类)

我们来看一下示例代码:

// reflection

 Run

上述代码首先获取​​Student​​的​​Class​​实例,然后,分别获取​​public​​字段、继承的​​public​​字段以及​​private​​字段,打印出的​​Field​​类似:

public int Student.score
public java.lang.String Person.name
private int Student.grade

一个​​Field​​对象包含了一个字段的所有信息:

  • ​getName()​​:返回字段名称,例如,​​"name"​​;
  • ​getType()​​:返回字段类型,也是一个​​Class​​实例,例如,​​String.class​​;
  • ​getModifiers()​​:返回字段的修饰符,它是一个​​int​​,不同的bit表示不同的含义。

以​​String​​类的​​value​​字段为例,它的定义是:

public final class String {
private final byte[] value;
}

我们用反射获取该字段的信息,代码如下:

Field f = String.class.getDeclaredField("value");
f.getName(); // "value"
f.getType(); // class [B 表示byte[]类型
int m = f.getModifiers();
Modifier.isFinal(m); // true
Modifier.isPublic(m); // false
Modifier.isProtected(m); // false
Modifier.isPrivate(m); // true
Modifier.isStatic(m); // false

获取字段值

利用反射拿到字段的一个​​Field​​实例只是第一步,我们还可以拿到一个实例对应的该字段的值。

例如,对于一个​​Person​​实例,我们可以先拿到​​name​​字段对应的​​Field​​,再获取这个实例的​​name​​字段的值:

// reflection
import java.lang.reflect.Field;

 Run

上述代码先获取​​Class​​实例,再获取​​Field​​实例,然后,用​​Field.get(Object)​​获取指定实例的指定字段的值。

运行代码,如果不出意外,会得到一个​​IllegalAccessException​​,这是因为​​name​​被定义为一个​​private​​字段,正常情况下,​​Main​​类无法访问​​Person​​类的​​private​​字段。要修复错误,可以将​​private​​改为​​public​​,或者,在调用​​Object value = f.get(p);​​前,先写一句:

f.setAccessible(true);

调用​​Field.setAccessible(true)​​的意思是,别管这个字段是不是​​public​​,一律允许访问。

可以试着加上上述语句,再运行代码,就可以打印出​​private​​字段的值。

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

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

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

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

标签:Field,java,获取,private,访问,字段,实例,public
From: https://blog.51cto.com/u_15692628/5785710

相关文章

  • java如何编写增强for循环呢?
    转自:​​http://www.java265.com/JavaCourse/202204/2982.html​​文笔者讲述java中for循环的简介说明,如下所示增强for循环增强for循环的功能:简化迭代器的书写格式增强f......
  • 今天聊下Java中的HashMap---Java中用的就很多的集合框架
    先说下HashMap的定义HashMap是一个散列表,存储的内容是键值对(key-value)映射。HashMap实现了Map接口,根据键的HashCode值存储数据,具有很快的访问速度,最多允许一条记录的键......
  • HMZK2【Zookeeper Java API】
    1Curator介绍原生zookeeperAPI的不足连接对象异步创建,需要开发人员自行编码等待连接没有自动重连超时机制watcher一次注册生效一次不支持递归创建树形节点curato......
  • java 武侠格斗生级版 javabean
    packagetest_3;importjava.util.Random;publicclassGame{//属性privateStringname;privateintblood;privatechargender;privateStringface;//长相是随机......
  • 力扣121(java&python)-买卖股票的最佳时机(简单)
    题目:给定一个数组prices,它的第 i个元素 prices[i]表示一支给定股票第i天的价格。你只能选择某一天买入这只股票,并选择在未来的某一个不同的日子卖出该股票。......
  • java springboot MINIO 集成
    <!--miniohttps://www.minio.org.cn/download.shtml#/linux--><dependency><groupId>io.minio</groupId><artifactId>minio</art......
  • javase重开2022年9月21日
    Boolean类型java中返回trueorfalse而在C语言中返回0表示false其余皆为true类型转换隐式类型转换隐式类型转换支持字节数小的类型自动转换为字节数大的类型,整数类......
  • java读取文件并统计出现前N个单词
    Java文件操作---输出单个文件中常出现的前N个英语单词-千幽行-博客园(cnblogs.com)packageclasstest;importjava.io.BufferedReader;importjava.io.File;imp......
  • Java多线程(1):线程生命周期
    您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来~ 从事Java开发这些年来,如果要问我Java当中最难的部分是什么?最有意思的部分是什么?最多人讨论的部分是什么?那我会毫不犹豫......
  • JavaScript中的Generator生成器的基本用法
    ES6入门-阮一峰:Generator函数1.介绍Generator生成器是ES6提供的一种异步编程解决方案。是一个极为灵活的结构,拥有在函数块中暂停和恢复代码执行的能力。执行Gen......