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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java反射,从0开始

發布時間:2025/3/19 java 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java反射,从0开始 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

靜態VS動態語言

Java?Reflection(反射)介紹

Java反射機制提供的功能

Java反射優點和缺點

反射相關的主要API

獲取運行時類的完整結構

反射的使用

有了Class對象,如何創建對象?

使用反射調用對象的指定方法

Object invoke(Object obj, Object[] args)

setAccessible

性能檢測

反射操作泛型

反射操作注解


靜態VS動態語言

動態語言:

? ? 是一類在運行時可以改變其結構的語言:例如新的函數、對象、甚至代碼可以被引進,已有的函數可以被刪除或是其他結構上的變化。通俗短說就是在運行時代碼可以根據某些條件改變自身結構。

? ? 主要動態語言:Object-C、C#、JavaScript、PHP、Python等。

靜態語言:

? ? 與動態語言相對應的,運行時結構不可變的語言就是靜態語言,如Java、C、C++。

? ? Java不是動態語言,但Java可以稱之為“準動態語言”。即Java有一定的動態性,我們可以利用反射機制獲得類似動態語言的特性。Java的動態性讓編程的時候更加靈活。

Java?Reflection(反射)介紹

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

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

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

Java反射機制提供的功能

? ? 在運行時判斷任意一個對象所屬的類。

? ? 在運行時構造任意一個類的對象。

? ? 在運行時判斷任意一個類所具有的成員變量和方法。

? ? 在運行時獲取泛型信息。

? ? 在運行時調用任意一個對象的成員變量和方法。

? ? 在運行時處理注解。

? ? 生成動態代理。

? ? ......

Java反射優點和缺點

? ? 優點:可以實現動態創建對象和編譯,體現出很大的靈活性。

? ? 缺點:對性能有影響。使用反射基本上是一種解釋操作,我們可以告訴JVM,我們希望做什么并且它滿足我們的要求。這類操作總是慢于直接執行相同的操作。

反射相關的主要API

? ? java.lang.Class:代表一個類

? ? java.lang.reflect.Method:代表類的方法。

? ? java.lang.reflect.Field:代表類的成員變量。

? ? java.lang.reflect.Constructor:代表類的構造器。

? ? ......

獲取運行時類的完整結構

? ? 通過反射獲取運行時類的完整結構:Field、Method、Constructor、Superclass、Interface、Annotation。

? ? 實現的全部接口、所繼承的父類、全部的構造器、全部的方法、全部的Field、注解等等。

import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method;//獲取類的信息 public class Test06 {public static void main(String[] args) throws Exception {Class c1 = Class.forName("com.myUtils.reflectUtils.learn.MyUser");MyUser user = new MyUser();c1 = user.getClass();//獲得類的名字System.out.println(c1.getName());//包名 + 類名System.out.println(c1.getSimpleName());//獲得類名//獲得類的屬性Field[] fields = c1.getFields();//獲取所有(只能找到public的屬性)屬性fields = c1.getDeclaredFields();//獲取所有(找到全部的屬性)屬性Field id = c1.getDeclaredField("id");//獲取指定屬性//獲得類的方法Method[] methods = c1.getMethods();//獲取所有(本類及其父類public的)方法methods = c1.getDeclaredMethods();//獲取所有(本類全部的)方法Method getName = c1.getMethod("getName", null);Method setName = c1.getMethod("setName", String.class);//需要參數類型(重載問題)//獲得構造器Constructor[] constructors = c1.getConstructors();Constructor constructor = c1.getConstructor(null);//也需要參數類型} }class MyUser{public Integer id;public String name;private int age;@Overridepublic String toString() {return "MyUser{" +"id=" + id +", name='" + name + '\'' +", age=" + age +'}';}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}private int getAge() {return age;}public void setAge(int age) {this.age = age;} }

反射的使用

有了Class對象,如何創建對象?

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

? ? 1.類必須有一個無參數的構造器。

? ? 2.類的構造器的訪問權限需要足夠。

沒有無參構造器、構造器權限不足的情況創建對象:

? ? 1.通過Class類的getDeclaredConstructor(Class ... parameterTypes)取得本類的指定形參類型的構造器。

? ? 2.向構造器的形參中傳遞一個對象數組進去,里面包含了構造器中所需的各個參數。

? ? 3.通過Constructor實例化對象。

使用反射調用對象的指定方法

通過反射,調用類中的方法,通過Method類完成。

? ? 1.通過Class類的getMethod(String name,Class ... parameterTypes)方法取得一個Method對象,并設置此方法操作時所需要的參數類型。

? ? 2.之后使用Object invoke(Object obj, Object[] args)進行調用,并向方法中傳遞要設置的obj對象的參數信息。

Object invoke(Object obj, Object[] args)

? ? Object對應原方法的返回值,若原方法無返回值,此時返回null。

? ? 若原方法為靜態方法,此時形參Object?obj可為null。

? ? 若原方法形參列表為空,則Object[] args為null。

? ? 若原方法聲明為private,則需要在調用此invoke()方法前,顯式調用方法對象的setAccessible(true)方法。將可訪問private的方法。

setAccessible

? ? Method和Field、Construetor對象都有setAccessible()方法。

? ? setAccessible作用是啟動和禁用訪問安全檢查的開關。

? ? 參數值為true則指示反射的對象在使用時應該取消Java語言訪問檢查。

?? ?? ? 提高反射的效率。如果代碼中必須用反射,而該句代碼需要頻繁的被調用,那么請設置為true;

?? ?? ? 使得原本無法訪問的私有成員也可以訪問。

? ? 參數值為false則指示反射的對象應該實施Java語言訪問檢查。

import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method;//通過反射創建對象 public class Test07 {public static void main(String[] args) throws Exception {Class c1 = Class.forName("com.myUtils.reflectUtils.learn.MyUser07");//構造一個對象MyUser07 user = (MyUser07) c1.newInstance();//實際上調用了無參構造器//通過構造器創建對象Constructor constructor = c1.getDeclaredConstructor(Integer.TYPE, String.class);user = (MyUser07) constructor.newInstance(5, "張三");//通過反射調用方法Method setName = c1.getDeclaredMethod("setName", String.class);setName.invoke(user, "李四");//(對象,參數)System.out.println(user.getName());//通過反射操作屬性Field name = c1.getDeclaredField("name");name.setAccessible(true);//設置為true就可以獲取到私有屬性、方法(關閉程序的安全監測)name.set(user, "王五");System.out.println(name.get(user));} } class MyUser07{private Integer id;private String name;public MyUser07(Integer id, String name) {this.id = id;this.name = name;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;} }

?

性能檢測

import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;public class Test08 {public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {/*** 普通時17ms* 反射耗時3398ms* 關閉檢測耗時1657ms*/test1();test2();test3();}//普通方式public static void test1(){User08 user08 = new User08();long startTime = System.currentTimeMillis();for (int i = 0; i < 1000000000; i++) {user08.getName();}long endTime = System.currentTimeMillis();System.out.println("普通時" + (endTime - startTime) + "ms");}//反射方式public static void test2() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {User08 user08 = new User08();Class c1 = user08.getClass();Method getName = c1.getDeclaredMethod("getName", null);long startTime = System.currentTimeMillis();for (int i = 0; i < 1000000000; i++) {getName.invoke(user08, null);}long endTime = System.currentTimeMillis();System.out.println("反射耗時" + (endTime - startTime) + "ms");}//反射方式,關閉檢測public static void test3() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {User08 user08 = new User08();Class c1 = user08.getClass();Method getName = c1.getDeclaredMethod("getName", null);getName.setAccessible(true);long startTime = System.currentTimeMillis();for (int i = 0; i < 1000000000; i++) {getName.invoke(user08, null);}long endTime = System.currentTimeMillis();System.out.println("關閉檢測耗時" + (endTime - startTime) + "ms");} } class User08{private Integer id;private String name;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;} }

反射操作泛型

? ? Java采用泛型擦除的機制來引入泛型,Java的泛型僅僅是給編譯器javac使用的,確保數據的安全性和免去強制類型轉換問題,但是,一旦編譯完成,所有和泛型有關的類型全部擦除。

? ? 為了通過反射操作這些類型,Java新增了ParameterizedType,GenericArrayType,TypeVariable和WildcardType集中類型來代表不能被歸一到class類中的類型但是又和原始類型齊名的類型。

ParameterizedType:表示一種參數化類型,比如Collection<String>。

GenericArrayType:表示一種元素類型是參數化類型或者類型變量的數組類型。

TypeVariable:是各種類型變量的公共父接口。

WildcardType:代表一種通配符類型表達式。

import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import java.util.Map;//通過反射獲取泛型 public class Test09 {public void test01(Map<String, User> map, List<Integer> list){System.out.println("test01");}public Map<String, User> test02(){System.out.println("test02");return null;}public static void main(String[] args) throws NoSuchMethodException {//獲取方法參數泛型Method method = Test09.class.getMethod("test01", Map.class, List.class);Type[] genericParameterTypes = method.getGenericParameterTypes();for (Type genericParameterType : genericParameterTypes) {System.out.println("#"+genericParameterType);if(genericParameterType instanceof ParameterizedType){Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();for (Type actualTypeArgument : actualTypeArguments) {System.out.println(actualTypeArgument);}}}//獲取返回值泛型Method method2 = Test09.class.getMethod("test02", null);Type genericReturnType = method2.getGenericReturnType();//獲取返回類型System.out.println("#"+genericReturnType);if(genericReturnType instanceof ParameterizedType){Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();for (Type actualTypeArgument : actualTypeArguments) {System.out.println(actualTypeArgument);}}} }

反射操作注解

import java.lang.annotation.*; import java.lang.reflect.Field;public class Test10 {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {Class c1 = Class.forName("com.myUtils.reflectUtils.learn.Student10");//通過反射獲取注解Annotation[] annotations = c1.getAnnotations();for (Annotation annotation : annotations) {System.out.println(annotation);}//獲得注解的value的值TableTest tableTest = (TableTest)c1.getAnnotation(TableTest.class);String value = tableTest.value();System.out.println(value);//db_student//獲得類指定的注解Field f = c1.getField("name");FieldTest annotation = f.getAnnotation(FieldTest.class);System.out.println(annotation.columnName());System.out.println(annotation.type());System.out.println(annotation.length());} }@TableTest("db_student") class Student10{@FieldTest(columnName = "db_id", type = "int", length = 10)private Integer id;@FieldTest(columnName = "db_name", type = "varchar", length = 20)private String name;public Student10() {}public Student10(Integer id, String name) {this.id = id;this.name = name;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;} }//類名的注解 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interface TableTest{String value(); } //屬性的注解 @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @interface FieldTest{String columnName();String type();int length(); }

?

總結

以上是生活随笔為你收集整理的Java反射,从0开始的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 九九热精品免费视频 | 亚洲综合三区 | 中文字幕va | 手机av网 | www色网| 亚洲激情图片区 | 青娱网电信一区电信二区电信三区 | 一级黄色美女视频 | 毛片你懂的 | 喷潮在线观看 | 超碰国产一区二区三区 | 日本老熟妇毛茸茸 | 国产男女av| 精品久久久噜噜噜久久久 | 国产成人麻豆精品午夜在线 | 美女户外露出 | 看全色黄大色黄大片女一次牛 | 亚洲午夜在线播放 | 久久久久久久久久久av | 日韩a级在线观看 | 国产a∨精品一区二区三区仙踪林 | 欧美视频一区二区在线 | 欧美日韩激情 | 麻豆一区二区三区在线观看 | 超碰网址 | 熊出没之冬日乐翻天免费高清观看 | 国产欧美一区二区精品性色99 | 久久久久久久久久久国产精品 | 新红楼梦2005锦江版高清在线观看 | 蜜桃av免费在线观看 | 午夜影院在线 | 亚洲成人福利在线 | 国产一区二区四区 | 99re6这里有精品热视频 | 亚洲免费观看高清 | 亚洲精品久久久 | 伊人66| 日本少妇xxxx软件 | 久本草精品 | 欧美自拍视频在线观看 | 丰满少妇xbxb毛片日本 | sese视频在线观看 | 男女视频在线观看 | 超碰国产97 | 91综合色| 亚洲一区久久 | 国产麻豆剧果冻传媒白晶晶 | 一本久久久| 国产ts系列| 高清欧美性猛交xxxx黑人猛交 | 国产精品久久久久久免费免熟 | 亚洲精品lv| 久一视频在线 | 欧美日韩爱爱 | 久久福利小视频 | 日韩在线观看你懂的 | 久久青青草原 | 琪琪色网 | 亚洲毛片精品 | 熟女人妻aⅴ一区二区三区60路 | 国产微拍精品一区 | 告诉我真相俄剧在线观看 | 日本精品免费在线观看 | 欧美日韩1区2区3区 亚洲日本精品视频 | 成人a免费 | 天天色视频 | 大陆熟妇丰满多毛xxxⅹ | 天天想你在线观看完整版高清 | 网友自拍一区 | 91偷拍网站 | 日韩欧美一卡二卡 | 欧美日韩一区二区综合 | 国产精品视频大全 | 亚洲自拍偷拍第一页 | 男女透逼视频 | 91一区二区在线观看 | 91黄在线看 | 老司机激情视频 | 国产网址在线 | 又白又嫩毛又多15p 超碰在线一区 | 久久亚洲一区 | 清纯唯美第一页 | 欧美日国产 | 日韩1024| 在线观看视频www | 国产全肉乱妇杂乱视频 | 俺来也俺也啪www色 欧洲一区二区视频 | 欧美成人久久久免费播放 | 亚州综合视频 | 天堂在线资源网 | 日本理论视频 | 中文字幕在线免费视频 | 亚洲av日韩av永久无码下载 | 涩涩999| 动漫av在线 | 欧美一卡二卡三卡四卡 | 一区二区传媒有限公司 | 青青草97 | 成年网站 |