java注解之運(yùn)行時(shí)修改字段的注解值操作
今天遇到需求:導(dǎo)入Excel時(shí)候列頭會(huì)發(fā)生變化,客戶是大爺要求你改代碼,
導(dǎo)入Excel是用easypoi做的,識(shí)別表頭是用注解@Excel(name = 'xxx')通過這個(gè)name來匹配
那你表頭要?jiǎng)樱疫@個(gè)注解是硬編碼
所以就有動(dòng)態(tài)設(shè)置這個(gè)表頭
public class JavaVo{@Excel(name = 'xxx')private String userName;//省略getset方法}ExcelImportUtil.importExcel(file.getInputStream(), configClass(JavaVo.class), params);
代碼如下
private Class configClass(Class c , String val) { Field[] fields = c.getDeclaredFields(); try { for(int i = 0;i < fields.length;i++){ Field f = fields[i]; Excel excelAn = f.getAnnotation(Excel.class);//Excel是注解類型 if(excelAn == null){ continue; } InvocationHandler h = Proxy.getInvocationHandler(excelAn); Field hField = h.getClass().getDeclaredField('memberValues'); // 因?yàn)檫@個(gè)字段事 private final 修飾,所以要打開權(quán)限 hField.setAccessible(true); // 獲取 memberValues Map memberValues = (Map) hField.get(h); // 修改 value 屬性值 這里修改的是@Excel(name = '姓名')//name是key memberValues.put('name', val); } } catch (Exception e) { e.printStackTrace(); } return c; }
補(bǔ)充知識(shí):java動(dòng)態(tài)修改 注解的值,控制對(duì)象轉(zhuǎn)化為json字符串的字段是否序列化
定義一個(gè)對(duì)象使用@JSONField控制該對(duì)象屬性是否需要序列化
import com.alibaba.fastjson.annotation.JSONField;import lombok.Data;@Datapublic class A { @JSONField(serialize = false) private String extendParams; @JSONField(serialize = true) private String sad;}
編寫工具類
import com.alibaba.fastjson.annotation.JSONField;import java.lang.reflect.Field;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;import java.util.Map;import lombok.val;/** * 動(dòng)態(tài)操作注解屬性 * @since 2020年8月13日20:49:26 */public class AnnotationUtils<T> { /** * 查看注解屬性 * @param t * @param name * @return * @throws NoSuchFieldException */ public Object getJSONFieldProp(T t, String name) throws NoSuchFieldException { Field field = t.getClass().getDeclaredField(name); JSONField annotation = field.getAnnotation(JSONField.class); val serialize = annotation.serialize(); return serialize; } /** * 修改注解屬性 * @param t * @param value * @return * @throws NoSuchFieldException * @throws IllegalAccessException */ public Object setJSONFieldProp(T t,String name, Object value) throws NoSuchFieldException, IllegalAccessException { Field field = t.getClass().getDeclaredField(name); JSONField annotation = field.getAnnotation(JSONField.class); InvocationHandler invocationHandler = Proxy.getInvocationHandler(annotation); Field memberValues = invocationHandler.getClass().getDeclaredField('memberValues'); memberValues.setAccessible(true); Map map = (Map) memberValues.get(invocationHandler); map.put('serialize',value); val serialize = annotation.serialize(); return serialize; }}
測(cè)試
import com.alibaba.fastjson.JSON;public class TT { public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { AnnotationUtils<A> aAnnotationUtils = new AnnotationUtils<>(); A a = new A(); a.setExtendParams('exex'); a.setSad('sadsad'); Object extendParams = aAnnotationUtils.getJSONFieldProp(a, 'extendParams');//查詢注解的值 System.out.println(extendParams.toString());// System.out.println(JSON.toJSONString(a)); Object extendParams1 = aAnnotationUtils.setJSONFieldProp(a, 'extendParams', true);//修改注解的值 System.out.println(extendParams1.toString()); System.out.println(JSON.toJSONString(a)); }}
去掉main里面的注解看看效果,這個(gè)好像是發(fā)生了jvm優(yōu)化導(dǎo)致的問題。。。
注釋第一個(gè)print 打印結(jié)果如下:
falsetrue{'extendParams':'exex','sad':'sadsad'}
不注釋第一個(gè)print 打印結(jié)果如下:
false{'sad':'sadsad'}true{'sad':'sadsad'}
接下來我們?cè)谧鲆粋€(gè)測(cè)試
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { List<A> aList = new ArrayList<>(); for(int i=0; i<10; i++){ AnnotationUtils<A> aAnnotationUtils = new AnnotationUtils<>(); A a = new A(); a.setExtendParams('exex'); a.setSad('sadsad'); if(i%2 == 0) {aAnnotationUtils.setJSONFieldProp(a, 'extendParams', true);//修改注解的值 } aList.add(a); } System.out.println(JSON.toJSONString(aList)); }
打印結(jié)果
[{'extendParams':'exex','sad':'sadsad'},{'extendParams':'exex','sad':'sadsad'},{'extendParams':'exex','sad':'sadsad'},{'extendParams':'exex','sad':'sadsad'},{'extendParams':'exex','sad':'sadsad'},{'extendParams':'exex','sad':'sadsad'},{'extendParams':'exex','sad':'sadsad'},{'extendParams':'exex','sad':'sadsad'},{'extendParams':'exex','sad':'sadsad'},{'extendParams':'exex','sad':'sadsad'}]
我本想用修改注解的方式來修改某個(gè)字段的序列化與不序列化,但是我發(fā)現(xiàn)注解是在class層面的并不是在對(duì)象層面。所以我的設(shè)想失敗了。。
以上這篇java注解之運(yùn)行時(shí)修改字段的注解值操作就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持好吧啦網(wǎng)。
相關(guān)文章:
1. 解決啟動(dòng)django,瀏覽器顯示“服務(wù)器拒絕訪問”的問題2. Yii2.0引入CSS,JS文件方法3. JSP數(shù)據(jù)交互實(shí)現(xiàn)過程解析4. vue使用webSocket更新實(shí)時(shí)天氣的方法5. Nginx+php配置文件及原理解析6. python virtualenv和flask安裝沒有名為flask的模塊7. 關(guān)于HTML5的img標(biāo)簽8. 討論CSS中的各類居中方式9. CSS3實(shí)現(xiàn)動(dòng)態(tài)翻牌效果 仿百度貼吧3D翻牌一次動(dòng)畫特效10. java中throws實(shí)例用法詳解
