日韩性视频-久久久蜜桃-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开始的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 久久国产网站 | 国产资源在线播放 | 国产精品成人一区二区三区 | 亚洲视频在线一区二区 | 精品人妻一区二区三 | 亚洲free性xxxx护士白浆 | 日本护士做爰视频 | 亚洲成人免费在线观看 | 久久综合久久88 | 嫩草影院一区二区三区 | 久操视频在线观看免费 | 免费看污片的网站 | 天天摸天天操天天爽 | 青草视频在线播放 | 一起射导航 | 美女自拍偷拍 | 91成人免费电影 | 久久香蕉精品视频 | 国产精品久久久久久久久久久久久久 | 精品区在线观看 | 天天爽天天插 | 国产日韩成人内射视频 | 国产午夜麻豆影院在线观看 | 欧美日韩国产片 | 免费啪啪网 | 污视频免费在线 | 欧美黄色一区二区三区 | 日本一区二区在线 | 亚洲不卡av一区二区 | 成人国产精品入口 | 日韩二三区| 亚洲一区二区三区不卡视频 | 依依成人在线 | 男女裸体影院高潮 | 国产乱码一区二区三区在线观看 | 欧美人与物videos另类 | 亚洲中文字幕一区 | 国产一区中文 | 丁香婷婷一区二区三区 | 日韩欧美大片在线观看 | 国产制服丝袜 | 天天碰天天干 | 天天操夜夜操夜夜操 | 亚洲精品6 | 午夜视频福利在线观看 | 久草手机在线观看 | 自拍偷拍第八页 | 国产五十路| 日韩一级影视 | 一级特黄特色的免费大片视频 | 日韩性生交大片免费看 | 天天综合色网 | 日本一级黄色大片 | 亚洲国产日韩在线 | 日本伦理一区二区 | 影音先锋在线视频 | 欧美国产一二三区 | 亚洲a级片 | 男人天堂影院 | 欧美日本在线视频 | 欧美网站免费 | 久久久精品综合 | 久久久久久久久久久久久久国产 | 狠狠网站| 黑人与日本少妇 | 国产精品视频在线播放 | 精品国产乱码一区二区 | 在线观看高清av | 9i看片成人免费看片 | 中文字幕亚洲一区二区三区五十路 | 国产精品一卡二卡三卡 | 99免费在线观看视频 | 国产精品一二区在线观看 | 久久精品久久精品 | 日本后进式猛烈xx00动态图 | 伊人黄色 | 一区二区 中文字幕 | 国产精品久久久久久免费 | 伊人综合影院 | 日韩一级片免费 | 精品少妇无码av无码专区 | 在线91观看 | 日本一区精品视频 | 91二区| 一卡二卡三卡 | 欧美色图亚洲天堂 | 小sao货水好多真紧h无码视频 | 人妻少妇精品中文字幕av蜜桃 | 色很久 | 伊人网在线视频观看 | 真实乱视频国产免费观看 | 黄色日批视频 | 久久发布国产伦子伦精品 | 亚洲av无码乱码国产精品 | 视频一二三区 | 国产精品一区2区 | 日韩av在线天堂 | 91在线精品一区二区三区 | 日日精 |