java反射机制

来源:互联网 发布:五五开和淘宝权决裂 编辑:程序博客网 时间:2024/05/05 01:15

Java反射机制

本节所有目录如下:

什么是JAVA的反射机制

Java反射是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等)、superclass(例如Object)、实现之interfaces(例如Cloneable),也包括fields和methods的所有信息,并可于运行时改变fields内容或唤起methods。

Java反射机制容许程序在运行时加载、探知、使用编译期间完全未知的classes。换言之,Java可以加载一个运行时才得知名称的class,获得其完整结构。

 

JDK中提供的Reflection API

Java反射相关的API在包java.lang.reflect中:

Member接口

该接口可以获取有关类成员(域或者方法)后者构造函数的信息。

AccessibleObject类

该类是域(field)对象、方法(method)对象、构造函数(constructor)对象的基础类。它提供了将反射的对象标记为在使用时取消默认 Java 语言访问控制检查的能力。

Array类

该类提供动态地生成和访问JAVA数组的方法。

Constructor类

提供一个类的构造函数的信息以及访问类的构造函数的接口。

Field类

提供一个类的域的信息以及访问类的域的接口。

Method类

提供一个类的方法的信息以及访问类的方法的接口。

Modifier类

提供了 static 方法和常量,对类和成员访问修饰符进行解码。

Proxy类

提供动态地生成代理类和类实例的静态方法。

 

JAVA反射机制提供了什么功能

    Java反射机制提供如下功能:

在运行时判断任意一个对象所属的类

在运行时构造任意一个类的对象

在运行时判段任意一个类所具有的成员变量和方法

在运行时调用任一个对象的方法

在运行时创建新类对象

在使用Java的反射功能时,基本首先都要获取类的Class对象,再通过Class对象获取其他的对象。

这里首先定义用于测试的类:

1.     class Type{  

2.      public int pubIntField;  

3.      public String pubStringField;  

4.      private int prvIntField;  

5.         

6.      public Type(){  

7.          Log("Default Constructor");  

8.      }  

9.         

10.     Type(int arg1, String arg2){  

11.         pubIntField = arg1;  

12.         pubStringField = arg2;  

13.            

14.         Log("Constructor with parameters");  

15.     }  

16.        

17.     public void setIntField(int val) {  

18.         this.prvIntField = val;  

19.     }  

20.     public int getIntField() {  

21.         return prvIntField;  

22.     }  

23.        

24.     private void Log(String msg){  

25.         System.out.println("Type:" + msg);  

26.     }  

27. }  

28.    

29. class ExtendType extends Type{  

30.     public int pubIntExtendField;  

31.     public String pubStringExtendField;  

32.     private int prvIntExtendField;  

33.        

34.     public ExtendType(){  

35.         Log("Default Constructor");  

36.     }     

37.        

38.     ExtendType(int arg1, String arg2){        

39.         pubIntExtendField = arg1;  

40.         pubStringExtendField = arg2;  

41.            

42.         Log("Constructor with parameters");  

43.     }  

44.        

45.     public void setIntExtendField(int field7) {  

46.         this.prvIntExtendField = field7;  

47.     }  

48.     public int getIntExtendField() {  

49.         return prvIntExtendField;  

50.     }  

51.        

52.     private void Log(String msg){  

53.         System.out.println("ExtendType:" + msg);  

54.     }  

55. }  

 

获取类的Class对象

Class 类的实例表示正在运行的 Java应用程序中的类和接口。获取类的Class对象有多种方式:

调用getClass

Boolean var1 = true;

Class<?> classType2 = var1.getClass();

System.out.println(classType2);

输出:class java.lang.Boolean

运用.class 语法

Class<?> classType4 = Boolean.class;

System.out.println(classType4);

输出:class java.lang.Boolean

运用static method Class.forName()

Class<?> classType5 = Class.forName("java.lang.Boolean");

System.out.println(classType5);

输出:class java.lang.Boolean

运用primitive wrapper classes的TYPE 语法

这里返回的是原生类型,和Boolean.class返回的不同

Class<?> classType3 = Boolean.TYPE;

System.out.println(classType3);        

输出:boolea

 

获取类的Fields

可以通过反射机制得到某个类的某个属性,然后改变对应于这个类的某个实例的该属性值。JAVA的Class<T>类提供了几个方法获取类的属性。

public Field  getField(String name)

返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共

成员字段

public Field[] getFields()

返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示

的类或接口的所有可访问公共字段

public Field getDeclaredField(Stringname)

返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定

已声明字段

public Field[] getDeclaredFields()

返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接

口所声明的所有字段

 Field f = chinese.getField("name");//public 属性

        Fieldf2 = chinese.getDeclaredField("age");//private 属性

        Field[]fs= chinese.getFields();

        Field[]fs2= chinese.getDeclaredFields();

       

        System.out.println(f);

        System.out.println(f2);

       

        for(Fieldfield:fs2) {

            System.out.println(field);

       }

 

获取类的Method

通过反射机制得到某个类的某个方法,然后调用对应于这个类的某个实例的该方法

Class<T>类提供了几个方法获取类的方法。

public Method getMethod(String name,Class<?>... parameterTypes)

返回一个 Method 对象,它反映此 Class

对象所表示的类或接口的指定公共成员方法

public Method[] getMethods()

返回一个包含某些 Method 对象的数组,

这些对象反映此 Class 对象所表示的类或

接口(包括那些由该类或接口声明的以及从

超类和超接口继承的那些的类或接口)的

公共 member 方法

public MethodgetDeclaredMethod(Stringname,Class<?>... parameterTypes)

返回一个 Method 对象,该对象反映此

Class 对象所表示的类或接口的指定已声明

方法

public Method[] getDeclaredMethods()

返回 Method 对象的一个数组,这些对象

反映此 Class 对象表示的类或接口声明的

所有方法,包括公共、保护、默认(包)

访问和私有方法,但不包括继承的方法

Method m = chinese.getMethod("walk");//公有方法名

        Methodm2= chinese.getDeclaredMethod("say");//私有方法名

        Method[]ms = chinese.getDeclaredMethods();

        Method[]ms2= chinese.getDeclaredMethods();

       

        System.out.println(m);

       

        for(Methodmethod : ms) {

            System.out.println(method);

        }

   

获取类的Constructor

通过反射机制得到某个类的构造器,然后调用该构造器创建该类的一个实例 

Class<T>类提供了几个方法获取类的构造器。

public Constructor<T> getConstructor(Class<?>... parameterTypes)

返回一个 Constructor 对象,它反映此 Class 对象所表示的类的

指定公共构造方法

public Constructor<?>[] getConstructors()

返回一个包含某些 Constructor 对象的数组,这些对象反映此

Class 对象所表示的类的所有公共构造方法

public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)

返回一个 Constructor 对象,该对象反映此 Class 对象所表示的

类或接口的指定构造方法

public Constructor<?>[] getDeclaredConstructors()

返回 Constructor 对象的一个数组,这些对象反映此 Class 对象

表示的类声明的所有构造方法。它们是公共、保护、默认(包)访

问和私有构造方法

 

 

Constructor[] cons=chinese.getConstructors();

        Constructor[]cons2=chinese.getDeclaredConstructors();

        Constructorcon=chinese.getConstructor(String.class);

        Constructorcon2=chinese.getDeclaredConstructor(String.class,int.class);

        Constructorcon3=chinese.getConstructor(new Class[]{});

       

        System.out.println("con:   "con);

        System.out.println("con2:  "+con2);

        System.out.println("con3   "+con3);

        for(Constructorc:cons2) {

            System.out.println(c);

     }

·        新建类的实例
       Class<T>
的函数newInstance
      
通过Constructor对象的方法newInstance

2.  调用类的函数
     

     通过反射获取类Method对象,调用Field的Invoke方法调用函数。

[java] view plaincopy

1.  Class<?> classType = ExtendType.class;  

2.  Object inst = classType.newInstance();  

3.  Method logMethod = classType.<strong>getDeclaredMethod</strong>("Log", String.class);  

4.  logMethod.invoke(inst, "test");  

5.     

6.  输出:  

7.  Type:Default Constructor  

8.  ExtendType:Default Constructor  

9.  <font color="#ff0000">Class com.quincy.ClassT can not access a member of class com.quincy.ExtendType with modifiers "private"</font>  

10.    

11. <font color="#ff0000">上面失败是由于没有权限调用private函数,这里需要设置Accessible为true;</font>  

12. Class<?> classType = ExtendType.class;  

13. Object inst = classType.newInstance();  

14. Method logMethod = classType.getDeclaredMethod("Log", String.class);  

15. <font color="#ff0000">logMethod.setAccessible(true);</font>  

16. logMethod.invoke(inst, "test");  

 

3.设置/获取类的属性值
        
通过反射获取类的Field对象,调用Field方法设置或获取值

[java] view plaincopy

1.  Class<?> classType = ExtendType.class;  

2.  Object inst = classType.newInstance();  

3.  Field intField = classType.getField("pubIntExtendField");  

4.  intField.<strong>setInt</strong>(inst, 100);  

5.      int value = intField.<strong>getInt</strong>(inst);  

 

4.动态创建代理类
        
动态代理源码分析

    代理模式:代理模式的作用=为其他对象提供一种代理以控制对这个对象的访问。

代理模式的角色:

抽象角色:声明真实对象和代理对象的共同接口

代理角色:代理角色内部包含有真实对象的引用,从而可以操作真实对象。

真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。

 

5.JAVA反射Class<T>类型源代码分析

6.JAVA反射原理分析
        Class
文件结构
        JVM加载类对象,对反射的支持

7。JAVA反射的应用

 

0 0
原创粉丝点击