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

歡迎訪問 生活随笔!

生活随笔

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

java

Java中,反射机制-Reflected

發布時間:2023/12/14 java 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java中,反射机制-Reflected 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、java的反射機制提供的功能:

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

二、反射相關的主要API:

  • java.lang.Class : 代表一個類
    1.程序經過javac.exe命令以后,會生成一個或多個字節碼文件(.calss后綴)。
    接著我們使用就java.exe命令對字節碼文件進行解釋運行,此過程相當于將某個字節碼文件加載帶內存中。上述過程稱之為類的加載。
    加載到內存中的類為運行時的類,運行時的類就作為Class的一個實例

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

    3.那些類型可以有Class對象
    1.class :外部類、成員內部類、靜態內部類、局部內部類、匿名類
    2.interface : 接口
    3.[] : 數組
    4.enum : 枚舉
    5.annotation : 注解@interface
    6.primitive type : 基本數據類型
    7.void

  • java.lang.reflect.Constructor : 代表類的構造器
    1.獲取當前類的public構造器
    Constructor[] 構造器對象名 = Class的實例名.getConstructors()

    2.獲取當前類的所有的構造器
    Constructor[] 構造器對象名 = Class的實例名.getDecleardConstructors()

    3.獲取指定的構造器
    Constructor 構造器對象名 = Class的實例名.getConstructor(參數1類型.class,…)

  • 創建運行時類的實例對象
    方式1:使用的是類中的指定的構造器創建的類對象【不常用】
    Constructor 構造器對象名 = Class的實例名.getConstructor(參數1類型.class,…) 獲取指定構造器對象
    構造器對象名.setAccessible(true) 表示允許操作private成員
    Object obj = 構造器對象名.newInstance(參數1,…) 通過指定構造器對象創建類的對象

    方式2:這樣直接使用的是類中的空參構造器創建的類對象【常用】
    Object obj = Class的實例名.newInstance()

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

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

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

    Class f.getType().getName() : 數據類型

    String f.getName() : 變量名

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

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

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

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

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

    3.調用方法
    非靜態方法:
    前提操作:m.setAccessible(true) 表示允許操作private成員
    調用:m.invoke(obj,實參1,…) obj表示給哪個對象的屬性設置,實參對應的方法的形參。invoke()返回值就是類中方法的返回值

    靜態方法:
    前提操作:m.setAccessible(true) 表示允許操作private成員
    調用:m.invoke(類.class,實參1,…) 類.class:表示當前類的靜態,實參對應的方法的形參。invoke()返回值就是類中方法的返回值

三、方法的補充:

1.獲取運行時類的父類
Class sp = Class的實例名.getSuperclass()

2.獲取運行時類的帶泛型的父類
Type sgp = Class的實例名.getGenericSuperclass()

3.獲取運行時類的帶泛型的父類的泛型(需要4步)
①Type sgp = Class的實例名.getGenericSuperclass(). : 獲取運行時類的帶泛型的父類
②ParameterizedType paramType = (parameterizedType)sgp : 強轉
③Type[] actTypeArg = paramType.getActualTypeArguments() : 獲取到實際的類型參數(也就是泛型)
④actTypeArg.getTypeName() : 獲取泛型名

4.獲取到當前運行時類的接口
Class[] interface = Class的實例名.getInterface()
如果想獲取到其父類的接口,那么得到父類然后在getInterface()

5.獲取當前運行時類所在的包
Package pk = Class的實例名.getPackage()

6.獲取當前運行時類聲明的注解
Annotation[] anno = Class的實例名.getAnnotations()

四、使用反射之前能對Person的操作:

  • 創建Person類的實例化
  • 通過對象當調用類中的非private類型的屬性、方法

五、使用反射之后能對Person的操作

  • 創建Person類的實例化(調用構造器)
  • 調用Person中的屬性
  • 調用Person中的方法
  • 調用Person中private的屬性、方法、構造器

上述過程的相關代碼舉例:

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.通過反射創建Person的對象objClass c = Person.class;Object newInstance = c.newInstance();System.out.println(newInstance.toString());//通過getConstructor(參數1類型.class,...)獲取構造器對象Constructor constructor = c.getConstructor(String.class,int.class);//獲取構造器對象Object obj = constructor.newInstance("Mike",22);//通過構造器對象實例化Person//通過對象調用Person的方法System.out.println(obj.toString()+"\n"); //通過反射創建Person的對象obj調用方法//2.調屬性Field age = c.getDeclaredField("age"); //通過getDeclaredField("屬性")獲取到該屬性的對象age.set(obj, 20); //修改屬性值System.out.println(obj.toString()+"\n");//3.調方法Method print = c.getDeclaredMethod("print");//通過getDeclaredMethod()獲取到該方法的對象print.invoke(obj); //調用該print()System.out.println();//4.調用private結構//4.1通過getDeclaredConstructor((參數1類型.class,...)獲取私有構造器對象Constructor privateConstructor = c.getDeclaredConstructor(String.class);//獲取私有構造器對象privateConstructor.setAccessible(true);Object obj2 = privateConstructor.newInstance("Tom");//創建對象System.out.println(obj2.toString());//4.2通過getDeclaredField("屬性名")獲取到私有屬性的對象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 + "]";}}

總結

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

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