文章目录
- 1.通过反射机制查看对象属性的值
- 1.1 实例演示
- 1.1.1.Employee.java
- 1.1.2 ReflectionTest.java
- 2.编写toString方法来查看任意对象内部信息
- 2.1 ObjectAnalyzer.java
- 2.2 ToStringTest.java
- 3.代码仓库地址
总结自《Java核心技术卷Ⅰ》
1.通过反射机制查看对象属性的值
利用反射机制可以查看在编译时还不清楚的对象域,就是具体运行时才能获取到的属性的值。
可以再程序运行时获取对象属性值,其中的关键是Field类中的get方法。
如果field是一个Field类型的对象,obj是某个包含field的类的对象,则field.get(obj)将返回一个对象,其就是obj名为field.getName()的属性的当前值。
除此之外我们还可以调用field.set(obj,value);将obj对象的名为field.getName()的属性设置成新值。
1.1 实例演示
1.1.1.Employee.java
public class Employee {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Employee(String name) {
this.name=name;
}
}
1.1.2 ReflectionTest.java
import java.lang.reflect.Field;
public class ReflectionTest {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
Employee harry = new Employee("Harry Hacker");
Class cl=harry.getClass();
Field f = cl.getDeclaredField("name");
//必须有,否则无法访问name的值会出错,作用是将所有域设置成可访问的
f.setAccessible(true);
Object v = f.get(harry);
//输出的是Harry Hacker
System.out.println(v);
f.set(harry,"牧之");
System.out.println(f.get(harry));
}
}
2.编写toString方法来查看任意对象内部信息
通过上面的学习,我们可以使用反射机制来写出通用的toString程序来打印出任意对象的所有的属性值信息。
在学习例子之前我们应先了解相关方法:
//此方法能获取当前类的父类的Class,可以用于访问定义在父类的属性
public native Class<? super T> getSuperclass();
2.1 ObjectAnalyzer.java
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
public class ObjectAnalyzer{
private ArrayList<Object> visited = new ArrayList<>();
/**
* 此方法利用放射将传入的对象toString化
* @param obj
* @return String
*/
public String toString(Object obj){
//首先判断传入的对象是否空对象,如果是直接返回null
if (obj == null) return "null";
//然后判断是否已经传入过相同的对象进来,如果是,返回 ...
if (visited.contains(obj)) return "...";
//将obj对象加入全局变量visited中
visited.add(obj);
//获得传入对象的class实例
Class<?> cl = obj.getClass();
//判断传入的对象是否是字符串对象,如果是,强转后直接返回
if (cl == String.class){
return (String) obj;
}
//基本数据类型直接返回其对应的基本类型数值描述
// if(cl==Integer.class||cl==Double.class||cl==Short.class||cl==Byte.class||cl==Float.class||cl==Long.class||cl==Boolean.class||cl==Character.class){
// return obj.toString();
// }
//如果是数组类型,则
if (cl.isArray()) {
String r = cl.getComponentType() + "[]{";
for (int i = 0; i < Array.getLength(obj); i++) {
if (i > 0){
r += ",";
}
//获得数组指定位置的元素
Object val = Array.get(obj, i);
//判断元素是不是基本类型
if (cl.getComponentType().isPrimitive()) {
r += val;
} else {
r += toString(val);
}
}
System.out.println(r);
return r + "}";
}
String r = cl.getName();
//将传入对象String化
do {
r += "[";
Field[] fields = cl.getDeclaredFields();
//这个操作可以让反射机制对私有属性也能进行操作
AccessibleObject.setAccessible(fields, true);
for (Field f : fields) {
if (!Modifier.isStatic(f.getModifiers())) {
if (!r.endsWith("[")) r += ",";
r += f.getName() + "=";
try {
Class t = f.getType();
Object val = f.get(obj);
//判断属性是不是基本类型
if (t.isPrimitive()) {
r += val;
}
else r += toString(val);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
r += "]";
//获得此类的父类型Class
cl = cl.getSuperclass();
} while (cl != null);
return r;
}
}
2.2 ToStringTest.java
public static void main(String[] args) {
Integer squares=new Integer(20);
System.out.println( new ObjectAnalyzer().toString(squares));
}
3.代码仓库地址
Java基础学习/src/main/java/Progress/exa30_2 · 严家豆/Study - 码云 - (gitee.com)