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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

JAVA反射机制Reflection详解

發布時間:2023/12/16 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JAVA反射机制Reflection详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

反射機制Reflection

1、靜態 VS 動態語言

2、Java Reflection

Java反射機制提供的功能

Java反射優點和缺點

3、反射相關的主要API

4、Class類

5、Java內存分析

6、創建運行時類的對象

7、有了Class對象,能做什么?

創建類的對象:調用Class對象的newInstance()方法

思考?難道沒有無參的構造器就不能創建對象了嗎?只要在操作的時候明確的調用類中的構造器,并將參數傳遞進去之后,才可以實例化操作。

步驟如下:

調用指定的方法

8、setAccessible

9、反射操作泛型


反射機制Reflection

1、靜態 VS 動態語言

動態語言
是一類在運行時可以改變其結構的語言:例如新的函數、對象、甚至代碼可以被引進,已有的
函數可以被刪除或是其他結構上的變化。通俗點說就是在運行時代碼可以根據某些條件改變自
身結構。
主要動態語言:Object-C、C#、JavaScript、PHP、Python等

//體現動態語言的代碼 function test() { var x = "var a=3;var b=5;alert(a+b)"; eval(x); } 靜態語言

與動態語言相對應的,運行時結構不可變的語言就是靜態語言。如Java、C、C++。
Java不是動態語言,但Java可以稱之為“準動態語言”。即Java有一定的動態性,我們可以利用
反射機制獲得類似動態語言的特性。Java的動態性讓編程的時候更加靈活!

2、Java Reflection

Reflection(反射)是Java被視為動態語言的關鍵,反射機制允許程序在執行期借助于Reflection API取
得任何類的內部信息,并能直接操作任意對象的內部屬性及方法。

Class c = Class.forName("java.lang.String")

加載完類之后,在堆內存的方法區中就產生了一個Class類型的對象(一個類只有一個Class對象),這
個對象就包含了完整的類的結構信息。我們可以通過這個對象看到類的結構。這個對象就像一面鏡子,
透過這個鏡子看到類的結構,所以,我們形象的稱之為:反射

package com.reflection; public class Test2 { public static void main(String[] args) { try { //通過反射獲取類的Class //--->查看JDK幫助文檔 Class<?> c1 = Class.forName("com.reflection.User"); //一個類被加載后 , 類的整個結構信息會被放到對應的Class對象中 System.out.println(c1); //一個類只對應一個Class對象 Class<?> c2 = Class.forName("com.reflection.User"); System.out.println(c1.hashCode()); System.out.println(c2.hashCode()); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } //1. 創建一個實體類 class User{ private int id; private int age; private String name; public User() { } public User(int id, int age, String name) { this.id = id; this.age = age; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User{" + "id=" + id + ", age=" + age + ", name=" + name + '}'; } }

Java反射機制提供的功能

在運行時判斷任意一個對象所屬的類
在運行時構造任意一個類的對象
在運行時判斷任意一個類所具有的成員變量和方法
在運行時獲取泛型信息
在運行時調用任意一個對象的成員變量和方法
在運行時處理注解
生成動態代理
……

Java反射優點和缺點

優點:可以實現動態創建對象和編譯,體現出很大的靈活性 !
缺點:對性能有影響。使用反射基本上是一種解釋操作,我們可以告訴JVM,我們希望做什么并且它滿
足我們的要求。這類操作總是慢于 直接執行相同的操作。

3、反射相關的主要API

java.lang.Class : 代表一個類
java.lang.reflect.Method : 代表類的方法
java.lang.reflect.Field : 代表類的成員變量
java.lang.reflect.Constructor : 代表類的構造器

4、Class類

在Object類中定義了該方法,此方法將被所有子類繼承

public final Class getClass();

以上的方法返回值的類型是一個Class類,此類是Java反射的源頭,實際上所謂反射從程序的運行結果來
看也很好理解,即:可以通過對象反射求出類的名稱。
對象照鏡子后可以得到的信息:某個類的屬性、方法和構造器、某個類到底實現了哪些接口。對于每個
類而言,JRE 都為其保留一個不變的 Class 類型的對象。一個 Class 對象包含了特定某個結構
(class/interface/enum/annotation/primitive type/void/[])的有關信息。
Class 本身也是一個類
Class 對象只能由系統建立對象
一個加載的類在 JVM 中只會有一個Class實例
一個Class對象對應的是一個加載到JVM中的一個.class文件
每個類的實例都會記得自己是由哪個 Class 實例所生成
通過Class可以完整地得到一個類中的所有被加載的結構
Class類是Reflection的根源,針對任何你想動態加載、運行的類,唯有先獲得相應的Class對象

package com.reflection; //測試各種類型獲得Class對象的方式 public class Test3 { public static void main(String[] args) throws ClassNotFoundException { Person person = new Student(); System.out.println("這個人是:"+person.name); //獲得class辦法一:通過對象獲得 Class clazz1 = person.getClass(); //獲得class辦法二:通過字符串獲得(包名+類名) Class clazz2 = Class.forName("com.reflection.Student"); //獲得class辦法三:通過類的靜態成員class獲得 Class clazz3 = Person.class; //獲得class辦法四:只針對內置的基本數據類型 Class clazz4 = Integer.TYPE; //獲得父類類型 Class clazz5 = clazz2.getSuperclass(); System.out.println(clazz1); System.out.println(clazz2); System.out.println(clazz3); System.out.println(clazz4); System.out.println(clazz5); } } class Person { public String name; public Person() { } public Person(String name) { this.name = name; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + '}'; } } class Student extends Person{ public Student(){ this.name = "學生"; } } class Teacher extends Person{ public Teacher(){ this.name = "老師"; } }

5、Java內存分析


?

6、創建運行時類的對象

通過反射獲取運行時類的完整結構
Field、Method、Constructor、Superclass、Interface、Annotation
實現的全部接口
所繼承的父類
全部的構造器
全部的方法
全部的Field
注解
。。。
小結
在實際的操作中,取得類的信息的操作代碼,并不會經常開發。
一定要熟悉java.lang.reflect包的作用,反射機制。

7、有了Class對象,能做什么?

創建類的對象:調用Class對象的newInstance()方法

類必須有一個無參數的構造器。
類的構造器的訪問權限需要足夠

思考?難道沒有無參的構造器就不能創建對象了嗎?只要在操作的時候明確的調用類中的構造器,并將參數傳遞進去之后,才可以實例化操作。

步驟如下:

通過Class類的getDeclaredConstructor(Class … parameterTypes)取得本類的指定形參類型
的構造器
向構造器的形參中傳遞一個對象數組進去,里面包含了構造器中所需的各個參數。
通過Constructor實例化對象

調用指定的方法

通過反射,調用類中的方法,通過Method類完成。
通過Class類的getMethod(String name,Class…parameterTypes)方法取得一個Method對
象,并設置此方法操作時所需要的參數類型。
之后使用Object invoke(Object obj, Object[] args)進行調用,并向方法中傳遞要設置的obj對
象的參數信息。

8、setAccessible

Method和Field、Constructor對象都有setAccessible()方法。
setAccessible作用是啟動和禁用訪問安全檢查的開關。
參數值為true則指示反射的對象在使用時應該取消Java語言訪問檢查。
提高反射的效率。如果代碼中必須用反射,而該句代碼需要頻繁的被調用,那么請設置為true。
使得原本無法訪問的私有成員也可以訪問
參數值為false則指示反射的對象應該實施Java語言訪問檢查

9、反射操作泛型

Java采用泛型擦除的機制來引入泛型 , Java中的泛型僅僅是給編譯器javac使用的,確保數據的安全性
和免去強制類型轉換問題 , 但是 , 一旦編譯完成 , 所有和泛型有關的類型全部擦除
為了通過反射操作這些類型 , Java新增了 ParameterizedType , GenericArrayType , TypeVariable
和 WildcardType 幾種類型來代表不能被歸一到Class類中的類型但是又和原始類型齊名的類型.
ParameterizedType : 表示一種參數化類型,比如Collection
GenericArrayType : 表示一種元素類型是參數化類型或者類型變量的數組類型
TypeVariable : 是各種類型變量的公共父接口
WildcardType : 代表一種通配符類型表達式

總結

以上是生活随笔為你收集整理的JAVA反射机制Reflection详解的全部內容,希望文章能夠幫你解決所遇到的問題。

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