标题:计算机毕业设计中Java反射—Field类使用
Java SE 8的Docs这样说:A Field provides information about, and dynamic access to, a single field of a class or an interface. The reflected field may be a class (static) field or an instance field.
简单理解就是:我们可用通过Field类对类或对象的field进行动态操作。
关于Field的一些方法:
其他的可以去Java的官方文档去查看。https://docs.oracle.com/javase/8/docs/api/
简单案例:
package io.ilss.reflection;/*** className User* description User** @author feng* @version 1.0* @date 2019-01-26 19:11*/public class User {private String username;private String password;private int sex;public String address; //注意这个是publicpublic User() {}public User(String username, String password) {this.username = username;this.password = password;}...//getter setter method}
package io.ilss.reflection;import java.lang.annotation.Annotation;import java.lang.reflect.Field;/*** className UserTest* description UserTest** @author feng* @version 1.0* @date 2019-01-26 19:12*/public class UserTest {public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {User user = new User("ilss", "ilss password");Class cls = user.getClass();//获取username名字的FieldField usernameField = cls.getDeclaredField("username");System.out.println(usernameField.toString());//获取user对象对应的usernameObject o = getSafe(usernameField, user);System.out.println("The username value of user is " + o);//获取基本数据类型user.setSex(1);Field sexField = cls.getDeclaredField("sex");sexField.setAccessible(true);sexField.setInt(user, 2);int sex = sexField.getInt(user);System.out.println("user sex : " + sex);//对user进行修改值 pubic不需要setAccessibleField addressField = cls.getDeclaredField("address");addressField.set(user, "ilss address");System.out.println("user address : " + user.getAddress());}public static Object getSafe(Field field, Object obj) {Object ret = null;try {if (field.isAccessible()) {ret = field.get(obj);} else {field.setAccessible(true);ret = field.get(obj);}} catch (IllegalAccessException e) {e.printStackTrace();}return ret;}}
需要说的点:
setAccessible方法。是Field继承自AccessibleObject类,AccessibleObject是Field、Method、Constuctor类的父类。简单理解意思就是 如果类型是private修饰的,你不可以直接访问,就需要设置访问权限为true.如果是public则不需要设置。
set和get调用的时候都需要确保可以访问,不然如果不能访问抛出IllegalAccessException。
制作一个通用的toString(Object obj)方法
package io.ilss.reflection;import java.lang.reflect.AccessibleObject;import java.lang.reflect.Array;import java.lang.reflect.Field;import java.lang.reflect.Modifier;import java.util.ArrayList;/*** className ObjectAnalyzer* description ObjectAnalyzer** @author feng* @version 1.0* @date 2019-01-26 19:34*/public class ObjectAnalyzer {private ArrayList<Object> visited = new ArrayList<>();public String toString(Object obj) {//无效处理if (obj == null) {return "null";}//注意 如果不判断contains可能会出现无限递归调用。if (visited.contains(obj)) {return "...";}//将已经处理的做记录visited.add(obj);Class cls = obj.getClass();//如果为String类型就直接返回if (cls == String.class) {return (String) obj;}//是否数组if (cls.isArray()) {//用StringBuilder来append字符串StringBuilder r = new StringBuilder(cls.getComponentType() + "[]{");//利用relect包的Array操作类来便利for (int i = 0; i < Array.getLength(obj); i++) {if (i > 0) {r.append(",");}Object val = Array.get(obj, i);// getComponentType() 得到数组对象元素的类型// isPrimitive()是判断是否是基本数据类型if (cls.getComponentType().isPrimitive()) {r.append(val);} else {//不是基本数据类型就递归调用。r.append(toString(val));}}return r + "}";}StringBuilder ret = new StringBuilder(cls.getName());do {ret.append("[");Field[] fields = cls.getDeclaredFields();//对fields数组的所有访问权限设置为trueAccessibleObject.setAccessible(fields, true);for (Field f : fields) {//只对非static参数处理if (!Modifier.isStatic(f.getModifiers())) {//如果不是第一个就加逗号if (!ret.toString().endsWith("[")) {ret.append(",");}ret.append(f.getName()).append("=");try {//对field的值进行获取Class t = f.getType();Object val = f.get(obj);//基本数据类型就直接append 不是就递归调用if (t.isPrimitive()) {ret.append(val);} else {ret.append(toString(val));}} catch (Exception e) {e.printStackTrace();}}}ret.append("]");//处理父类cls = cls.getSuperclass();}while (cls != null);return ret.toString();}public String toString() {//利用自己调用toString(this)来实现自己的toStringreturn this.toString(this);}}
注意:
里面有个Array类,是java.lang.reflect包下一个数组操作类。代码里的调用意思都不难理解。就不解释了
调用类
package io.ilss.reflection;import java.util.ArrayList;import java.util.List;/*** className ObjectAnalyzerTest* description ObjectAnalyzerTest** @author feng* @version 1.0* @date 2019-01-26 19:30*/public class ObjectAnalyzerTest {public static void main(String[] args) {List<Integer> squares = new ArrayList<>();for (int i = 0; i < 5; i++) {squares.add(i * i);}System.out.println(new ObjectAnalyzer().toString(squares));System.out.println(new ObjectAnalyzer().toString());User[] arr = new User[10];System.out.println(new ObjectAnalyzer().toString(arr));User user = new User("ilss", "ilss password");System.out.println(new ObjectAnalyzer().toString(user));}}
作者:苡仁ilss
链接:https://www.jianshu.com/p/bd864b93b420
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
版权所有© 帮我毕业网 并保留所有权利