最近在写一些导入导出Excel的代码,涉及到反射相关的部分,发现自己民之前的知识体系有问题,整理一下。
bean 部分代码:
public class Study implements Serializable {private String name;public String getName() { System.out.println("com.zhouxianglh.bean.Study.getName()....................."); return name;}public void setName(String name) { this.name = name;}}
反射调用代码:
public static void main(String[] args) throws Exception {Study stu = new Study();stu.setName("abcd");//方式1Field field = stu.getClass().getDeclaredField("name");field.setAccessible(true);System.out.println("type1:" + field.get(stu));//方式2PropertyDescriptor propertyDescriptor = new PropertyDescriptor("name", stu.getClass());Method method = propertyDescriptor.getReadMethod();System.out.println("type1:" + method.invoke(stu));}
输出结果:
type1:abcdcom.zhouxianglh.bean.Study.getName().....................type1:abcd
上面的例子中通过两种方式获取Bean对象的值:
方式1 获取Field 字段,之后通过禁用安全检查 field.setAccessible(true); ,之后直接获取到对象的属性值,从输出结果来看并没有经过get方法。使用的方法是
Object sun.misc.Unsafe.getObject(Object paramObject, long paramLong)
public native Object getObject(Object paramObject, long paramLong);
很明显通过native方法直接获取属性值,所以并没有通过get方法。
方式2 获取get方法 propertyDescriptor.getReadMethod(); ,之后通过反射调用get方法获取值。
之前一直认为即使是反射,如果没有get方法,也不可以获取私有属性的值。这是一个误区。
上面两种获取值的方法比较一下,很明显第一种方式暴露了对象的实现,很糟糕的方式。如果有这个需要不如把对象属性设置为public,大家都知道bean为何要把属性设置为private,所以方式1糟糕的地方就很明显了