日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Field setAccessible()方法的作用及應用場景

作者:咖啡不苦** 更新時間: 2022-06-08 編程語言

一、更改string的value值,但是其指向不變

曾經看到過這樣的一個題目:

public static void main(String[] args) {
String s=new String(“abc”);
//在這中間添加N行代碼,但是必須保證s引用的指向不變,最終將輸出變成abcd
System.out.println(s);
}

看到如上題目,該如何加代碼,能讓其指向不變呢?解決辦法如下:

String s = new String(“abc”);
Field value = s.getClass().getDeclaredField(“value”);
value.setAccessible(true);
value.set(s, “abcd”.toCharArray());
System.out.println(s);

采用了反射機制實現了其功能實現,我們發現代碼中有一個setAccessible(true);如果去掉這句話會如何呢?

Exception in thread "main" java.lang.IllegalAccessException: Class FileTest can not access a member of class java.lang.String with modifiers "private final"
	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.set(Field.java:761)
	at FileTest.main(FileTest.java:17)

Class FileTest can not access a member of class java.lang.String with modifiers "private final"意思就是類 FileTest 不能訪問帶有修飾符“private final”的類 java.lang.String 的成員。

二、實體demo 獲取成員變量的值

1)私有成員變量

在平常創建正常model使用過程中,都是設置private類型的成員變量

public class Student {
    private String name;
    private Integer age;
        Student student=new Student();
		student.setName("huo");
		Field value1=Student.class.getDeclaredField("name");
		// value1.setAccessible(true);
		System.out.println(value1.isAccessible());
		System.out.println(value1.get(student));

執行如上代碼,會輸出什么?

false
Exception in thread "main" java.lang.IllegalAccessException: Class FileTest can not access a member of class Student 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 FileTest.main(FileTest.java:27)

其實這種情況和上述對string的demo是一樣的。 那么我們能如何獲取值呢?
兩種辦法:

  1. 將私有變量改為公有變量
  2. 配置 value1.setAccessible(true);

2)公有成員變量

public class Student {
    public String name;
    public Integer age;

看執行結果:

false
huo

3)setAccessible

        Student student=new Student();
		student.setName("huo");
		Field value1=Student.class.getDeclaredField("name");
		value1.setAccessible(true);
		System.out.println(value1.isAccessible());
		System.out.println(value1.get(student));

看執行結果:

true
huo

4)成員變量為public,isAccessible會輸出什么?

可以測試一下,答案為true,為什么呢?

三、setAccessible的作用到底是什么?

在這里插入圖片描述
看如上解釋,清晰明了。為TRUE表示反射在使用時應禁止java語言訪問檢查,值為false表示反射對象應強制執行java語言訪問檢查。

這樣就能很明了設置了setAccessible為true之后,就能編輯final變量以及訪問private變量了。
下篇講述java API之AccessibleObject,也就是Field的父類到底干了點什么?

原文鏈接:https://blog.csdn.net/huo065000/article/details/119919185

欄目分類
最近更新