日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

sqlite字段是否存在_学习廖雪峰的JAVA教程---反射(访问字段)

發布時間:2024/9/30 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 sqlite字段是否存在_学习廖雪峰的JAVA教程---反射(访问字段) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

對任意的一個Object實例,只要我們獲取了它的Class,就可以獲取它的一切信息。

我們先看看如何通過Class實例獲取字段信息。Class類提供了以下幾個方法來獲取字段:

  • Field getField(name):根據字段名獲取某個public的field(包括父類)
  • Field getDeclaredField(name):根據字段名獲取當前類的某個field(不包括父類)
  • Field[] getFields():獲取所有public的field(包括父類)
  • Field[] getDeclaredFields():獲取當前類的所有field(不包括父類)

我們來看一下示例代碼:

// reflectionpublic class Main { public static void main(String[] args) throws Exception { Class stdClass = Student.class; // 獲取public字段"score": System.out.println(stdClass.getField("score")); // 獲取繼承的public字段"name": System.out.println(stdClass.getField("name")); // 獲取private字段"grade": System.out.println(stdClass.getDeclaredField("grade")); }}class Student extends Person { public int score; private int grade;}class Person { public String name;}

上述代碼首先獲取Student的Class實例,然后,分別獲取public字段、繼承的public字段以及private字段,打印出的Field類似:

public int Student.scorepublic java.lang.String Person.nameprivate int Student.grade

一個Field對象包含了一個字段的所有信息:

  • getName():返回字段名稱,例如,"name";
  • getType():返回字段類型,也是一個Class實例,例如,String.class;
  • getModifiers():返回字段的修飾符,它是一個int,不同的bit表示不同的含義。

以String類的value字段為例,它的定義是:

public final class String { private final byte[] value;}

我們用反射獲取該字段的信息,代碼如下:

Field f = String.class.getDeclaredField("value"); //返回一個Field對象(包含字段名稱、字段類型、字段修飾符)f.getName(); // "value"f.getType(); // class [B 表示byte[]類型int m = f.getModifiers();Modifier.isFinal(m); // trueModifier.isPublic(m); // falseModifier.isProtected(m); // falseModifier.isPrivate(m); // trueModifier.isStatic(m); // false

獲取字段值

利用反射拿到字段的一個Field實例只是第一步,我們還可以拿到一個實例對應的該字段的值。

例如,對于一個Person實例,我們可以先拿到name字段對應的Field,再獲取這個實例的name字段的值:

// reflectionimport java.lang.reflect.Field;public class Main { public static void main(String[] args) throws Exception { Object p = new Person("Xiao Ming"); Class c = p.getClass(); Field f = c.getDeclaredField("name"); Object value = f.get(p); System.out.println(value); // "Xiao Ming" }}class Person { private String name; public Person(String name) { this.name = name; }}

上述代碼先獲取Class實例,再獲取Field實例,然后,用Field.get(Object)獲取指定實例的指定字段的值。

運行代碼,如果不出意外,會得到一個IllegalAccessException,這是因為name被定義為一個private字段,正常情況下,Main類無法訪問Person類的private字段。要修復錯誤,可以將private改為public,或者,在調用Object value = f.get(p);前,先寫一句:

f.setAccessible(true);

調用Field.setAccessible(true)的意思是,別管這個字段是不是public,一律允許訪問。

可以試著加上上述語句,再運行代碼,就可以打印出private字段的值。

有童鞋會問:如果使用反射可以獲取private字段的值,那么類的封裝還有什么意義?

答案是正常情況下,我們總是通過p.name來訪問Person的name字段,編譯器會根據public、protected和private決定是否允許訪問字段,這樣就達到了數據封裝的目的。

而反射是一種非常規的用法,使用反射,首先代碼非常繁瑣,其次,它更多地是給工具或者底層框架來使用,目的是在不知道目標實例任何信息的情況下,獲取特定字段的值

此外,setAccessible(true)可能會失敗。如果JVM運行期存在SecurityManager,那么它會根據規則進行檢查,有可能阻止setAccessible(true)。例如,某個SecurityManager可能不允許對java和javax開頭的package的類調用setAccessible(true),這樣可以保證JVM核心庫的安全。

設置字段值

通過Field實例既然可以獲取到指定實例的字段值,自然也可以設置字段的值。

設置字段值是通過Field.set(Object, Object)實現的,其中第一個Object參數是指定的實例,第二個Object參數是待修改的值。示例代碼如下:

// reflectionimport java.lang.reflect.Field;public class Main { public static void main(String[] args) throws Exception { Person p = new Person("Xiao Ming"); System.out.println(p.getName()); // "Xiao Ming" Class c = p.getClass(); Field f = c.getDeclaredField("name"); f.setAccessible(true); f.set(p, "Xiao Hong"); System.out.println(p.getName()); // "Xiao Hong" }}class Person { private String name; public Person(String name) { this.name = name; } public String getName() { return this.name; }}

運行上述代碼,打印的name字段從Xiao Ming變成了Xiao Hong,說明通過反射可以直接修改字段的值。

同樣的,修改非public字段,需要首先調用setAccessible(true)。

小結

Java的反射API提供的Field類封裝了字段的所有信息:

通過Class實例的方法可以獲取Field實例:getField(),getFields(),getDeclaredField(),getDeclaredFields();

通過Field實例可以獲取字段信息:getName(),getType(),getModifiers();

通過Field實例可以讀取或設置某個對象的字段,如果存在訪問限制,要首先調用setAccessible(true)來訪問非public字段。

通過反射讀寫字段是一種非常規方法,它會破壞對象的封裝。

【關鍵:

  • 利用反射拿到字段的一個Field實例只是第一步,我們還可以拿到一個實例對應的該字段的值
  • 使用反射,首先代碼非常繁瑣,其次,它更多地是給工具或者底層框架來使用,目的是在不知道目標實例任何信息的情況下,獲取特定字段的值
  • 總結

    以上是生活随笔為你收集整理的sqlite字段是否存在_学习廖雪峰的JAVA教程---反射(访问字段)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。