上一篇介绍了Java反射之构造方法反射。这次我们在说一说如何反射类中的成员变量并用作一个简单案例。

[一]Field类

Filed类代表字段,包含字段拥有的所有属性,比如修饰符,变量类型,值等等,Filed类中有获得这些属性的方法。

和Constructor类一样都继承了java.lang.reflect.AccessibleObject类,该类中有方法来判断和设置私有属性能否访问。

下面举个演示如何修改、获得某个类中的变量:

Point类:

public class Point {
public int x;
private int y;
public static int z = 10; public Point(int x, int y) {
super();
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}

测试方法:

public static void main(String[] args) throws Exception {
Point p = new Point(3,4);
Class cls = p.getClass();
//1、获得Point类中所有的成员变量
Field[] fields = cls.getFields();
//打印
for(Field field : fields){
//get(p);获得对象p的所有成员变量
System.out.println(field.get(p));
} //2、获得Point类中的指定x,y,z变量
Field fieldX = cls.getField("x");
Field fieldY = cls.getField("y");
Field fieldZ = cls.getField("z");
//分别对应对象p
System.out.println("x:"+fieldX.get(p)+" y:"+fieldY.get(p)+" z:"+fieldZ.get(null)); }

结果:

3
10
Exception in thread "main" java.lang.NoSuchFieldException: y
at java.lang.Class.getField(Class.java:1584)
at club.leyvan.muzile.ConstructDemo.main(ConstructDemo.java:20)

Class类中的getFields():获得该类的所有字段作为Field类的对象。

Class类中的getFields(String name):获得该类中和参数同名的字段。

Filed类中的get(p):绑定这个字段是哪一个对象身上的。例子中传了p,代表该方法将field对应对象的成员字段绑定给特定对象p及为对象p中对象名称字段的值。

静态变量属于类所以不需要绑定特定对象,传入null即可获得静态字段值。

第一部分的代码除了私有变量都打印出来了,而第二部分报了错,没有y这个私有变量,暂时我们可以看出私有变量是无法读取的。我们现在把代码修改以下,让它可以获得私有变量的值。

修改后代码如下:

public static void main(String[] args) throws Exception {
Point p = new Point(3,4);
Class cls = p.getClass();
//1、获得Point类中所有的成员变量
Field[] fields = cls.getFields();
//打印
for(Field field : fields){
//get(p);获得对象p的所有成员变量
System.out.println(field.get(p));
} //2、获得Point类中的指定x,y,z变量
Field fieldX = cls.getField("x");
//修改部分↓↓
Field fieldY = cls.getDeclaredField("y");
fieldY.setAccessible(true);
//修改部分↑↑
Field fieldZ = cls.getField("z");
//分别对应对象p
System.out.println("x:"+fieldX.get(p)+" y:"+fieldY.get(p)+" z:"+fieldZ.get(null)); }

结果:

3
10
x:3 y:4 z:10

Class类中getDeclaredField(String name):获得私有变量

Field类继承的类java.lang.reflect.AccessibleObject中有setAccessible(boolean b):设置是否可以访问私有成员。

上面的方法又叫暴力反射,可以暴力获取私有成员。

[二]案例:利用反射的方式将一个类中的String类型的变量中所有的"b"修改为"a"

Bean类:

package club.leyvan.muzile;

public class Bean {
public int i1 = 10;
public String str1 = "basketball";
private String str2 = "breakfast";
private static String str3 = "bbc";
@Override
public String toString() {
return "Bean [i1=" + i1 + ", str1=" + str1 + ", str2=" + str2 + "]";
} public static String getStr3(){
return "str3: "+str3;
}
}

测试方法:

public static void main(String[] args) throws Exception {
//获得class
Class cls = Class.forName("club.leyvan.muzile.Bean");
//创建一个对象 默认调用无参构造方法
Bean obj = (Bean)cls.newInstance();
//获得所有字段
Field[] fields = cls.getDeclaredFields();
//扫描所有字段
for(Field field : fields){
//class对象只有一份,所以使用==更好
if(field.getType() == String.class){
//判断是否是
if(!field.isAccessible()){
field.setAccessible(true);
}
//判断是否是静态字段
//getModifiers()获得所有的修饰符
//boolean isStatic = Modifier.isStatic(field.getModifiers());
String oldValue = (String)field.get(obj);
String newValue = oldValue.replace('b', 'a');
field.set(obj, newValue);
}
}
System.out.println(obj+Bean.getStr3());
}

结果:

Bean [i1=10, str1=aasketaall, str2=areakfast]str3: aac

其中field.getModifiers():获得所有的修饰符

Modifier.isStatic():通过获得修饰符判断是否是static

field.set(obj,value):修改绑定对象的值

下一篇我们说Java反射之成员方法的反射

Java反射之成员变量的反射的更多相关文章

  1. Android(java)学习笔记109:通过反射获取成员变量和成员方法并且使用

    一.反射获取成员变量并且使用: 1.获取字节码文件对象:         Class c = Class.forName("cn.itcast_01.Person"); 2.使用无 ...

  2. Android(java)学习笔记50:通过反射获取成员变量和成员方法并且使用

    1. 反射获取成员变量并且使用: (1)获取字节码文件对象:         Class c = Class.forName("cn.itcast_01.Person"); (2) ...

  3. java 27 - 4 反射之 通过反射获取成员变量并使用

    类Field: 提供有关类或接口的单个字段的信息,以及对它的动态访问权限. A:获得类的成员变量 数组: 1.getFields(公共类的) 2.getDeclaredFields(所有类型的) B: ...

  4. java中的成员变量和局部变量区别

    1.作用域不同 成员变量的作用域在整个类内部都是可见,可用的: 局部变量的作用域仅限于定义它的方法,不能被其它方法调用: 2.初始值不同 java会给成员变量一个初始值,初始值为0: java不会给局 ...

  5. Java学习笔记十五:Java中的成员变量和局部变量

    Java中的成员变量和局部变量 一:成员变量: 成员变量在类中定义,用来描述对象将要有什么 成员变量可以被本类的方法使用,也可以被其他类的方法使用,成员变量的作用域在整个类内部都是可见的 二:局部变量 ...

  6. Java的类成员变量、实例变量、类变量,成员方法、实例方法、类方法

    总是被这些相似的概念搞晕,查阅了资料后做个小总结,以变量为例,方法辨析类似. 1.多胞胎名字汇总辨析 成员变量和成员方法是范围最大的定义,提到成员变量就可以理解成你所定义在一个类体中的各类变量的统称, ...

  7. java 反射 - 获取成员变量的值.

    通过反射,可以获取所有声明的成员变量(包括所有的),代码如下: package spt.test.src; public class Person { private String name = &q ...

  8. Java基础---基础加强---增强for循环、自动拆装箱及享元、枚举的作用、实现带有构造方法、透彻分析反射的基础_Class类、成员变量的反射、数组参数的成员方法进行反射、数组的反射应用

    在perference 加content Assist 可以设置快捷键 透视图与视图 透视图:Debug和java主窗口 视图:每一个小窗口就是视图 高版本的java可运行低版本的java版本 常见的 ...

  9. java反射--获取成员变量信息

    获取成员变量信息 代码及说明: public static void printFieldMessage(Object obj) { //要获取类的信息,首先要获取类的类类型 Class c=obj. ...

随机推荐

  1. Python面向对象三大特征

    继承 面向对象中的继承就是继承的类直接拥有被继承类的属性而不需要在自己的类体中重新再写一遍,其中被继承的类叫做父类.基类,继承的类叫做派生类.子类.在python3中如果不指定继承哪个类,默认就会继承 ...

  2. 升级本地已安装的 Node 和 npm 版本

    Mac升级本地已经安装的NodeJs和Npm到最新版,可以使用一下方式进行升级和更新. 其实windos上升级nodejs也很简单,只需在nodejs官网下载安装最新的msi即可. 值得注意的是安装时 ...

  3. MOOC(3)- python发送请求,返回的json数据被转码

    https://www.cnblogs.com/yoyoketang/p/10339210.html 问题:发送post请求,对post请求返回的json数据格式化,但是返回的结果被转码了 json. ...

  4. Docker企业级镜像仓库harbor(vmware 中国团队)

    第一步:安装docker和docker-compose 第二步:下载harbor-offline-installer-v1.3.0.tgz 第三步:上传到/opt,并解压 第四步:修改harbor.c ...

  5. webdriver访问各个浏览器驱动下载及安装

    这里首先需要查看一下自己安装的selenium版本 查看步骤: windows系统打开cmd命令行输入:pip show selenium查看结果如下: 进入到selenium官网查看版本信息 sel ...

  6. GCD实现多个定时器,完美避过NSTimer的三大缺陷(RunLoop、Thread、Leaks)

    定时器在我们每个人做的iOS项目里面必不可少,如登录页面倒计时.支付期限倒计时等等,一般来说使用NSTimer创建定时器: + (NSTimer *)timerWithTimeInterval:(NS ...

  7. yii框架通过控制台命令创建定时任务

    假设Yii项目路径为 /home/apps 1. 创建文件 /home/apps/web/protected/commands/console.php $yii = '/home/apps/frame ...

  8. Sed 实记 · laoless's Blog

    sed编辑命令 p 打印匹配行 = 打印文件行号 a 在定位行之后追加文本 i 在定位行之前插入文本 d 删除定位行 c 用新文本替换定位文本 s 使用替换模式替换相应模式 r 从另一个文件读取文本 ...

  9. 7-43 jmu-python-字符串异常处理 (20 分)

    输入一行字符串及下标,能取出相应字符.程序能对不合法数据做相应异常处理. 输入格式: 行1:输入一字符串 行2:输入字符下标 输出格式: 下标非数值异常,输出下标要整数 下标越界,输出下标越界 数据正 ...

  10. Lambda表达式(JDK8)

    在说Lambda表达式之前,先介绍一下函数式接口 函数式接口 就是只定义了一个抽象方法的接口,我们可以使用注解@Functionallnterface,来强约束这种接口为函数式接口.如Runnable ...