您的位置:首页 > 编程语言 > Java开发

Java Reflection深入理解变量(Field)

2018-02-22 23:14 399 查看
使用Java反射机制你可以运行期检查一个类的变量信息(成员变量)或者获取或者设置变量的值。

通过使用java.lang.reflect.Field类就可以实现上述功能。

以下涉及实例通用代码MyObject.java:

package com.lanhuigu.reflect.common;

public class MyObject {
/** 公开成员变量 */
public String fieldName = "Test-Field-Name";
/** 私有属性 */
private String userName;
private String password;

/** 构造器 */
public MyObject() {

}

public MyObject(String userName) {
this.userName = userName;
}

public MyObject(String userName, String password) {
this.userName = userName;
this.password = password;
}

/** getter and setter methods */
public String getFieldName() {
return fieldName;
}

public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}
}

获取Field对象
可以通过Class对象获取Field对象,如下例:

Class myClass = ...//获取Class对象
Field[] methods = myClass.getFields();

返回的Field对象数组包含了指定类中声明为公有的(public)的所有变量集合。

eg:
package com.lanhuigu.reflect.fields;

import java.lang.reflect.Field;

public class Test2 {
public static void main(String[] args) {
try {
/** 获取Class对象 */
Class myClass = Class.forName("com.lanhuigu.reflect.common.MyObject");
/** 获取对象所有公开(public)属性 */
Field[] fields = myClass.getFields();
/** 循环输出变量名称 */
for (Field field : fields) {
System.out.println(field.getName());
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}


如果你知道你要访问的变量名称,你可以通过如下的方式获取指定的变量:

Class myClass = MyObject.class

Field field = myClass.getField("fieldName");

上面的例子返回的Field类的实例对应的就是在MyObject类中声明的名为fieldName的成员变量,如下:

public class MyObject{

  /** 公开成员变量 */

  public String fieldName = "Test-Field-Name";

}

在调用getField()方法时,如果根据给定的方法参数没有找到对应的变量,那么就会抛出NoSuchFieldException。

eg:
package com.lanhuigu.reflect.fields;

import java.lang.reflect.Field;

public class Test3 {
public static void main(String[] args) {
try {
/** 获取Class对象 */
Class myClass = Class.forName("com.lanhuigu.reflect.common.MyObject");
/** 根据属性名获取Field */
Field field = myClass.getField("fieldName");
/** 输出变量名称 */
System.out.println(field.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}

变量名称
一旦你获取了Field实例,你可以通过调用Field.getName()方法获取他的变量名称,如下例:

Field field = ... //获取Field对象
String fieldName = field.getName();

变量类型
你可以通过调用Field.getType()方法来获取一个变量的类型(如String, int等等),如下例:

Field field = myClass.getField("fieldName");
Object fieldType = field.getType();

eg:

package com.lanhuigu.reflect.fields;

import java.lang.reflect.Field;

public class Test4 {
public static void main(String[] args) {
try {
/** 获取Class对象 */
Class myClass = Class.forName("com.lanhuigu.reflect.common.MyObject");
/** 根据属性名获取Field */
Field field = myClass.getField("fieldName");
/** 输出变量类型 */
Object fieldType = field.getType();
System.out.println("变量类型:" + fieldType);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}


获取或设置(get/set)变量值
一旦你获得了一个Field的引用,你就可以通过调用Field.get()或Field.set()方法,获取或者设置变量的值,如下例:

Class myClass = MyObject.class;

Field field = myClass.getField("fieldName");

MyObject objectInstance = new MyObject();
Object value = field.get(objectInstance);

field.set(objetInstance, value);
传入Field.get()/Field.set()方法的参数objetInstance应该是拥有指定变量的类的实例。

在上述的例子中传入的参数是MyObject类的实例,是因为fieldName是MyObject类的实例。
如果变量是静态变量的话(public static)那么在调用Field.get()/Field.set()方法的时候

传入null做为参数而不用传递拥有该变量的类的实例。
eg:

package com.lanhuigu.reflect.fields;

import com.lanhuigu.reflect.common.MyObject;

import java.lang.reflect.Field;

public class Test5 {
public static void main(String[] args) {
try {
/** 获取Class对象 */
Class myClass = Class.forName("com.lanhuigu.reflect.common.MyObject");
/** 根据属性名获取Field */
Field field = myClass.getField("fieldName");
MyObject objectInstance = new MyObject();
/** 通过get获取值 */
Object value = field.get(objectInstance);
System.out.println("Field.get()获取值:" + value.toString());
/** 通过set设置值 */
String fieldNameValue = "0000000000000000-new-value";
field.set(objectInstance, fieldNameValue);
/** 从新获取set进去的新值 */
Object value2 = field.get(objectInstance);
System.out.println("Field.get()获取Field.set()的新值:" + value2.toString());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: