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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

反射机制-Reflected

發(fā)布時(shí)間:2023/12/14 编程问答 60 豆豆
生活随笔 收集整理的這篇文章主要介紹了 反射机制-Reflected 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、java的反射機(jī)制提供的功能:

  • 在運(yùn)行時(shí)判斷任意一個(gè)對(duì)象所屬的類(lèi)
  • 在運(yùn)行時(shí)構(gòu)造任意一個(gè)類(lèi)的對(duì)象
  • 在運(yùn)行時(shí)判斷任意一個(gè)類(lèi)所具有的成員變量和方法
  • 運(yùn)行時(shí)獲取泛型信息
  • 在運(yùn)行時(shí)調(diào)用任意一個(gè)對(duì)象的成員變量和方法
  • 在運(yùn)行時(shí)處理注解
  • 生成動(dòng)態(tài)代理

二、反射相關(guān)的主要API:

  • java.lang.Class : 代表一個(gè)類(lèi)
    1.程序經(jīng)過(guò)javac.exe命令以后,會(huì)生成一個(gè)或多個(gè)字節(jié)碼文件(.calss后綴)。
    接著我們使用就java.exe命令對(duì)猴哥字節(jié)碼文件進(jìn)行解釋運(yùn)行,此過(guò)程相當(dāng)于將某個(gè)字節(jié)碼文件加載帶內(nèi)存中。上述過(guò)程稱(chēng)之為累的加載。
    加載到內(nèi)存中的類(lèi)為運(yùn)行時(shí)的類(lèi),運(yùn)行時(shí)的類(lèi)就作為Class的一個(gè)實(shí)例

    2.獲取Class的實(shí)例方式
    方式1(掌握):Class<> c = 類(lèi)名.class
    方式2(掌握):類(lèi)名 對(duì)象名 = new 類(lèi)名()
    Class c = 對(duì)象名.getClass()
    方式3(掌握):Class c = Class.forName(String classPath)(注意:會(huì)拋異常)

    3.那些類(lèi)型可以有Class對(duì)象
    1.class :外部類(lèi)、成員內(nèi)部類(lèi)、靜態(tài)內(nèi)部類(lèi)、局部?jī)?nèi)部類(lèi)、匿名類(lèi)
    2.interface : 接口
    3.[] : 數(shù)組
    4.enum : 枚舉
    5.annotation : 注解@interface
    6.primitive type : 基本數(shù)據(jù)類(lèi)型
    7.void

  • java.lang.reflect.Constructor : 代表類(lèi)的構(gòu)造器
    1.獲取當(dāng)前類(lèi)的public構(gòu)造器
    Constructor[] 構(gòu)造器對(duì)象名 = Class的實(shí)例名.getConstructors()

    2.獲取當(dāng)前類(lèi)的所有的構(gòu)造器
    Constructor[] 構(gòu)造器對(duì)象名 = Class的實(shí)例名.getDecleardConstructors()

    3.獲取指定的構(gòu)造器
    Constructor 構(gòu)造器對(duì)象名 = Class的實(shí)例名.getConstructor(參數(shù)1類(lèi)型.class,…)

  • 創(chuàng)建運(yùn)行時(shí)類(lèi)的實(shí)例對(duì)象
    方式1:使用的是類(lèi)中的指定的構(gòu)造器創(chuàng)建的類(lèi)對(duì)象【不常用】
    Constructor 構(gòu)造器對(duì)象名 = Class的實(shí)例名.getConstructor(參數(shù)1類(lèi)型.class,…) 獲取指定構(gòu)造器對(duì)象
    構(gòu)造器對(duì)象名.setAccessible(true) 表示允許操作private成員
    Object obj = 構(gòu)造器對(duì)象名.newInstance(參數(shù)1,…) 通過(guò)指定構(gòu)造器對(duì)象創(chuàng)建類(lèi)的對(duì)象

    方式2:這樣直接使用的是類(lèi)中的空參構(gòu)造器創(chuàng)建的類(lèi)對(duì)象【常用】
    Object obj = Class的實(shí)例名.newInstance()

  • java.lang.reflect.Field : 代表類(lèi)的成員變量
    1.獲取到類(lèi)中public屬性(包含父類(lèi))【不建議使用
    方法1:
    Field[] f = Class的實(shí)例名.getFields()
    方法2:
    Field f = Class的實(shí)例名.getField(屬性名)

    2.獲取到類(lèi)中自己的所有屬性(不含有父類(lèi)):【建議使用】
    方法1:
    Field[] f = Class的實(shí)例名.getDeclaredFields()
    方法2:
    Field f = Class的實(shí)例名.getDeclaredField(屬性名)

    3.獲取到屬性的權(quán)限修飾符、數(shù)據(jù)類(lèi)型、變量名。(了解)
    int f.getModifiers() : 權(quán)限修飾符(0代表默認(rèn),1代表public,2代表private)

    Class f.getType().getName() : 數(shù)據(jù)類(lèi)型

    String f.getName() : 變量名

    4.設(shè)置、獲取 屬性的值
    非靜態(tài)的屬性:
    前提操作:f.setAccessible(true) 表示允許操作private成員
    設(shè)置:f.set(obj,value) obj表示給哪個(gè)對(duì)象的屬性設(shè)置,value為設(shè)置的值
    獲取:f.get(obj) obj表示獲取哪個(gè)對(duì)象的屬性值,有返回值

    靜態(tài)的屬性:
    前提操作:f.setAccessible(true) 表示允許操作private成員
    設(shè)置:f.set(類(lèi).class,value) 類(lèi).class:表示當(dāng)前類(lèi)的靜態(tài),value為設(shè)置的值
    獲取:f.get(類(lèi).class) 類(lèi).class:表示當(dāng)前類(lèi)的靜態(tài),有返回值

  • java.lang.reflect.Method : 代表類(lèi)的方法
    1.獲取到類(lèi)中public方法(包含父類(lèi))【不推薦使用】
    方法1:
    Method[] m = Class的實(shí)例名.getMethods()

    方法2:
    Method m = Class的實(shí)例名.getMethod(方法名,形參列表(默認(rèn)為空))

    2.獲取到類(lèi)中自己的所有方法(不含有父類(lèi))【推薦使用】
    方法1:
    Method[] m = Class的實(shí)例名.getDeclaredMethods()
    方法2:
    Method m = Class的實(shí)例名.getDeclaredMethod(方法名,形參列表(默認(rèn)為空)) 例:String型的形參列表:String.class

    3.調(diào)用方法
    非靜態(tài)方法:
    前提操作:m.setAccessible(true) 表示允許操作private成員
    調(diào)用:m.invoke(obj,實(shí)參1,…) obj表示給哪個(gè)對(duì)象的屬性設(shè)置,實(shí)參對(duì)應(yīng)的方法的形參。invoke()返回值就是類(lèi)中方法的返回值

    靜態(tài)方法:
    前提操作:m.setAccessible(true) 表示允許操作private成員
    調(diào)用:m.invoke(類(lèi).class,實(shí)參1,…) 類(lèi).class:表示當(dāng)前類(lèi)的靜態(tài),實(shí)參對(duì)應(yīng)的方法的形參。invoke()返回值就是類(lèi)中方法的返回值

三、方法的補(bǔ)充:

1.獲取運(yùn)行時(shí)類(lèi)的父類(lèi)
Class sp = Class的實(shí)例名.getSuperclass()

2.獲取運(yùn)行時(shí)類(lèi)的帶泛型的父類(lèi)
Type sgp = Class的實(shí)例名.getGenericSuperclass()

3.獲取運(yùn)行時(shí)類(lèi)的帶泛型的父類(lèi)的泛型(需要4步)
①Type sgp = Class的實(shí)例名.getGenericSuperclass(). : 獲取運(yùn)行時(shí)類(lèi)的帶泛型的父類(lèi)
②ParameterizedType paramType = (parameterizedType)sgp : 強(qiáng)轉(zhuǎn)
③Type[] actTypeArg = paramType.getActualTypeArguments() : 獲取到實(shí)際的類(lèi)型參數(shù)(也就是泛型)
④actTypeArg.getTypeName() : 獲取泛型名

4.獲取到當(dāng)前運(yùn)行時(shí)類(lèi)的接口
Class[] interface = Class的實(shí)例名.getInterface()
如果想獲取到其父類(lèi)的接口,那么得到父類(lèi)然后在getInterface()

5.獲取當(dāng)前運(yùn)行時(shí)類(lèi)所在的包
Package pk = Class的實(shí)例名.getPackage()

6.獲取當(dāng)前運(yùn)行時(shí)類(lèi)聲明的注解
Annotation[] anno = Class的實(shí)例名.getAnnotations()

四、使用反射之前能對(duì)Person的操作:

  • 創(chuàng)建Person類(lèi)的實(shí)例化
  • 通過(guò)對(duì)象當(dāng)調(diào)用類(lèi)中的非private類(lèi)型的屬性、方法

五、使用反射之后能對(duì)Person的操作

  • 創(chuàng)建Person類(lèi)的實(shí)例化(調(diào)用構(gòu)造器)
  • 調(diào)用Person中的屬性
  • 調(diào)用Person中的方法
  • 調(diào)用Person中private的屬性、方法、構(gòu)造器

上述過(guò)程的相關(guān)代碼舉例:

import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;public class ReflectionTest {public static void main(String[] args) throws Exception {Person p1 = new Person("Joney",18);System.out.println(p1.age);System.out.println(p1.toString()+"\n");System.out.println("**************************");//1.通過(guò)反射創(chuàng)建Person的對(duì)象objClass c = Person.class;Object newInstance = c.newInstance();System.out.println(newInstance.toString());//通過(guò)getConstructor(參數(shù)1類(lèi)型.class,...)獲取構(gòu)造器對(duì)象Constructor constructor = c.getConstructor(String.class,int.class);//獲取構(gòu)造器對(duì)象Object obj = constructor.newInstance("Mike",22);//通過(guò)構(gòu)造器對(duì)象實(shí)例化Person//通過(guò)對(duì)象調(diào)用Person的方法System.out.println(obj.toString()+"\n"); //通過(guò)反射創(chuàng)建Person的對(duì)象obj調(diào)用方法//2.調(diào)屬性Field age = c.getDeclaredField("age"); //通過(guò)getDeclaredField("屬性")獲取到該屬性的對(duì)象age.set(obj, 20); //修改屬性值System.out.println(obj.toString()+"\n");//3.調(diào)方法Method print = c.getDeclaredMethod("print");//通過(guò)getDeclaredMethod()獲取到該方法的對(duì)象print.invoke(obj); //調(diào)用該print()System.out.println();//4.調(diào)用private結(jié)構(gòu)//4.1通過(guò)getDeclaredConstructor((參數(shù)1類(lèi)型.class,...)獲取私有構(gòu)造器對(duì)象Constructor privateConstructor = c.getDeclaredConstructor(String.class);//獲取私有構(gòu)造器對(duì)象privateConstructor.setAccessible(true);Object obj2 = privateConstructor.newInstance("Tom");//創(chuàng)建對(duì)象System.out.println(obj2.toString());//4.2通過(guò)getDeclaredField("屬性名")獲取到私有屬性的對(duì)象Field name = c.getDeclaredField("name");name.setAccessible(true);name.set(obj2, "Aimy");//修改屬性值System.out.println(obj2.toString());} } class Person{private String name;public int age;public Person(String name, int age) {super();this.name = name;this.age = age;}private Person(String name) {super();this.name = name;}public Person() {super();}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public void print() {System.out.println("我是Person的print()");}@Overridepublic String toString() {return "Person [name=" + name + ", age=" + age + "]";}}

總結(jié)

以上是生活随笔為你收集整理的反射机制-Reflected的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。