咱們來看下例子:java
@Data public class Demo { public String name; private String title; }
public class Test { public static void main(String[] args) { try { Class clazz = Class.forName("com.lian.demo.Demo"); Demo demo = (Demo) clazz.newInstance(); demo.setName("name1"); demo.setTitle("title1"); Field[] fields = clazz.getDeclaredFields(); Arrays.stream(fields).forEach(field -> { try { System.out.println("成員變量"+field.getName()+"的值爲:"+field.get(demo)); } catch (IllegalAccessException e) { e.printStackTrace(); } }); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
執行結果以下:安全
成員變量name的值爲:name1 java.lang.IllegalAccessException: Class com.lian.demo.Test can not access a member of class com.lian.demo.TestDemo with modifiers "private" at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102) at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296) at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288) at java.lang.reflect.Field.get(Field.java:390) at com.lian.demo.Test.lambda$main$0(Test.java:38) at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580) at com.lian.demo.Test.main(Test.java:31)
說明反射機制中沒法獲取到private成員的值。那到底有沒有辦法獲取到?固然是有。Java反射機制提供的setAccessible()方法能夠取消Java的權限控制檢查。spa
Arrays.stream(fields).forEach(field -> { boolean flag = field.isAccessible(); System.out.println(field.getName() + ":" + flag); try { //設置該屬性老是可訪問 field.setAccessible(true); System.out.println("成員變量"+field.getName()+"的值爲:"+field.get(demo)); } catch (IllegalAccessException e) { System.out.println(e.getMessage()); } //還原可訪問權限 field.setAccessible(flag); });
這下沒問題了,能夠獲取到了。setAccessible(true)取消了Java的權限控制檢查,但不是改變方法或字段的訪問權限。code
而對於setAccessible()方法是否會破壞類的訪問規則,產生安全隱患,我在知乎上面看到的一篇回答貌似頗有道理:blog