java 的反射用不好容易走火入魔?还可以用内省啊!,网易 java 面试题和答案
public void setAge(int age) {
this.age = age;
this.adult = age >= ADULT_AGE;
}
public boolean isAdult() {
return adult;
}
public String toString() {
return MessageFormat.format("age:{0},adult:{1}", age, adult);
}
}
/**
@author 二当家的白帽子 https://le-yi.blog.csdn.net/
*/
public class Test {
/**
利用反射修改对象属性
@param o
@param fieldName
@param value
@throws NoSuchFieldException
@throws IllegalAccessException
*/
public static void changeObjectFieldByReflection(Object o, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException {
Field field = o.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(o, value);
}
/**
利用内省修改对象属性
@param o
@param fieldName
@param value
@throws NoSuchFieldException
@throws IllegalAccessException
*/
public static void changeObjectFieldByIntrospector(Object o, String fieldName, Object value) throws IntrospectionException, InvocationTargetException, IllegalAccessException {
PropertyDescriptor pd = new PropertyDescriptor(fieldName, o.getClass());
pd.getWriteMethod().invoke(o, value);
}
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IntrospectionException, InvocationTargetException {
Person p = new Person();
changeObjectFieldByReflection(p, "age", 20);
System.out.println("反射修改属性破坏类的封装,使其内部状态错误:");
System.out.println(p);
changeObjectFieldByIntrospector(p, "age", 18);
System.out.println("内省修改属性未破坏类的封装:");
System.out.println(p);
}
}
复制代码
可以看到,反射由于是直接修改属性,所以破坏了类中封装的逻辑(20 岁却不是成年)。
而内省由于修改属性还是调用了 set 方法,也就是说和正常修改对象属性调用了相同的方法,所以类的封装性不会遭到破坏。
当然由于内省其实本质也是反射,可以说是封装了反射,所以如果反射用的正确,也是安全的,我们可以根据属性名去获取相应的 set 和 get 方法,然后再去调用,但是这种情况下内省使用起来就更方便,毕竟没有必要重复发明一个车轮子,圆形轮子已经是很多年很多年智慧的结晶了。
那么问题来了,既然内省就是调用 set 和 get 方法,那我为什么不直接调用 set 和 get 方法,而要使用内省呢?
使用内省也一样可以写出通用的工具
================
既然内省可以动态获取信息,那就和反射一样,可以实现出通用工具或者框架哦。我们这里实现一个可以拷贝任意类型两个对象的属性值的工具方法。
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDesc 《一线大厂 Java 面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》开源 riptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.MessageFormat;
class Person {
/**
18 岁成年
*/
private static final int ADULT_AGE = 18;
/**
名字
*/
private final String name;
/**
身高
*/
private int height;
/**
年龄
*/
private int age;
/**
是否成年
*/
private Java 开源项目【ali1024.coding.net/public/P7/Java/git】 boolean adult;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getAge() {
return age;
结尾
这不止是一份面试清单,更是一种”被期望的责任“,因为有无数个待面试者,希望从这篇文章中,找出通往期望公司的”钥匙“,所以上面每道选题都是结合我自身的经验于千万个面试题中经过艰辛的两周,一个题一个题筛选出来再次对好答案和格式做出来的,面试的答案也是再三斟酌,深怕误人子弟是小,影响他人仕途才是大过,也希望您能把这篇文章分享给更多的朋友,让他帮助更多的人,帮助他人,快乐自己,最后,感谢您的阅读。
由于细节内容实在太多啦,在这里我花了两周的时间把这些答案整理成一份文档了,在这里只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
评论