java 反射和内省

本文深入探讨了Java反射和内省机制的核心概念与应用场景,包括动态获取类信息及调用方法的方式。提供了丰富的示例代码,展示了如何利用反射创建对象、获取属性,以及使用内省来获取Bean属性描述。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1       反射和内省

反射 (Reflection) JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
内省 (Introspector),是“看透class”的能力(内省、内观、反省)。
2.1    “Class” object的取得途径
Java允许我们从多种管道为一个class生成对应的Class object

Class object 诞生管道
示例
运用getClass()
注:每个class 都有此函数
String str = "abc";
Class c1 = str.getClass();
运用
Class.getSuperclass()2
Button b = new Button();
Class c1 = b.getClass();
Class c2 = c1.getSuperclass();
运用static method
Class.forName()
(最常被使用)
Class c1 = Class.forName ("java.lang.String");
Class c2 = Class.forName ("java.awt.Button");
Class c3 = Class.forName ("java.util.LinkedList$Entry");
Class c4 = Class.forName ("I");
Class c5 = Class.forName ("[I");
运用
.class 语法
Class c1 = String.class;
Class c2 = java.awt.Button.class;
Class c3 = Main.InnerClass.class;
Class c4 = int.class;
Class c5 = int[].class;
运用
primitive wrapper classes
TYPE 语法
 
Class c1 = Boolean.TYPE;
Class c2 = Byte.TYPE;
Class c3 = Character.TYPE;
Class c4 = Short.TYPE;
Class c5 = Integer.TYPE;
Class c6 = Long.TYPE;
Class c7 = Float.TYPE;
Class c8 = Double.TYPE;
Class c9 = Void.TYPE;
1Java 允许多种管道生成Class object
 
以图2java.util.LinkedList为例,将Java class的定义大卸八块,每一块分别对应图3所示的Reflection API
 
package java.util;                 //(1)
import java.lang.*;                //(2)
public class LinkedList<E>              //(3)(4)(5)
extends AbstractSequentialList<E>               //(6)
implements List<E>, Queue<E>,
Cloneable, java.io.Serializable              //(7)
{
private static class Entry<E> { }//(8)
public LinkedList() { }                  //(9)
public LinkedList(Collection<? extends E> c) { }
public E getFirst() { }                  //(10)
public E getLast() { }
private transient Entry<E> header = ;        //(11)
private transient int size = 0;
}
2:将一个Java class 大卸八块,每块相应于一个或一组Reflection APIs(图3)。
 
2.3    Java classes 各成份所对应的Reflection APIs
2的各个Java class成份,分别对应于图3Reflection API,其中出现的PackageMethodConstructorField等等classes,都定义于java.lang.reflect。本表并非Reflection APIs 的全部。

Java class 内部模块(参见3
Java class 内部模块说明
相应之Reflection API,多半为Class methods
返回值类型(return type)
(1) package
class隶属哪个package
getPackage()
Package
(2) import
class导入哪些classes
无直接对应之API
解决办法见5-2
 
(3) modifier
class(或methods, fields)的属性
 
int getModifiers()
Modifier.toString(int)
Modifier.isInterface(int)
int
String
bool
(4) class name or interface name
class/interface
名称getName()
String
(5) type parameters
参数化类型的名称
getTypeParameters()
TypeVariable <Class>[]
(6) base class
base class(只可能一个)
getSuperClass()
Class
(7) implemented interfaces
实现有哪些interfaces
getInterfaces()
Class[]
 
(8) inner classes
内部classes
getDeclaredClasses()
Class[]
(8') outer class
如果我们观察的class 本身是inner classes,那么相对它就会有个outer class
getDeclaringClass()
Class
(9) constructors
构造函数getDeclaredConstructors()
不论 public private 或其它access level,皆可获得。另有功能近似之取得函数。
Constructor[]
(10) methods
操作函数getDeclaredMethods()
不论 public private 或其它access level,皆可获得。另有功能近似之取得函数。
Method[]
(11) fields
字段(成员变量)
getDeclaredFields()不论 public private 或其它access level,皆可获得。另有功能近似之取得函数。
Field[]
3Java class大卸八块后(如图2),每一块所对应的Reflection API
Model.java
 
package RefInt;
 
import java.io.Serializable;
import java.util.Date;
 
publicclass Model implements Serializable {
 
    privatestaticfinallongserialVersionUID = -162798607158235676L;
 
    publicstatic String id = "111111";
    public String name = "haha";
    privateintage ;
    private Date b;
   
    publicint getAge() {
       returnage;
    }
    publicvoid setAge(int age) {
       this.age = age;
    }
    public Date getB() {
       returnb;
    }
    publicvoid setB(Date b) {
       this.b = b;
    }
    public String getName() {
       returnname;
    }
    publicvoid setName(String name) {
       this.name = name;
    }
}
RefInt.java
 
package RefInt;
 
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
 
publicclass RefInt {
   
    publicstaticvoid main(String[] args) {
       System.out.println("f_1()");
       f_1();
       System.out.println("f_2()");
       f_2();
       System.out.println("f_3()");
       f_3();
       System.out.println("f_4()");
       f_4();
       System.out.println("getArrayByIndex()");
       int[] a = {10,2,3,5};
       String[] s = {"aabc","aaabc","def","f"};
       // 数组排序
       Arrays.sort(s);
       System.out.println(getArrayByIndex(s,0));
       System.out.println(getArrayByIndex(a,0));
       System.out.println(getArrayByIndex(a,3));
       Arrays.sort(a);
       System.out.println(getArrayByIndex(a,0));
       System.out.println(getArrayByIndex(a,3));
       Array.set(a, 0, -1);
       System.out.println(getArrayByIndex(a,0));
    }
 
    /**
     *获得数组o下标为index的值
     *@paramo
     *@paramindex
     *@return
     */
    publicstatic Object getArrayByIndex(Object o , int index) {
       return Array.get(o, index);
    }
   
    /**
     *通过类名得到类描述对象
     *通过类描述对象获得类模式(此类为public
     */
    publicstaticvoid f_4() {
       try {
           Class class_my = Class.forName("RefInt.Model");
           int m = class_my.getModifiers();
           System.out.println(class_my.getModifiers());
           if (Modifier.isPublic(m))
                System.out.println("public");
 
       } catch (ClassNotFoundException e) {
           e.printStackTrace();
       } catch (SecurityException e) {
           e.printStackTrace();
       } catch (IllegalArgumentException e) {
           e.printStackTrace();
       }
    }
   
    /**
     *通过类名得到类描述对象
     *通过类描述对象获得属性对象列表并显示其属性
     */
    publicstaticvoid f_3() {
       try {
           Class class_my = Class.forName("RefInt.Model");
           // 只能得到属性是publicField
           Field[] publicFields = class_my.getFields();
           for (int i = 0; i < publicFields.length; i++) {
              String fieldName = publicFields[i].getName();
              Class typeClass = publicFields[i].getType();
              String fieldType = typeClass.getName();
              System.out.println("Name: " + fieldName + ", Type: " + fieldType);
           }
       } catch (ClassNotFoundException e) {
           e.printStackTrace();
       }
    }
    /**
     *通过实体对象获得类描述对象
     *通过累描述对象获得指定属性对象
     *通过属性对象实例得到属性名和属性值
     */
    publicstaticvoid f_2() {
       Model model = new Model();
       //属性必须是public,否则抛出NoSuchFieldException异常
       String sfiled = "name";
       Class class_my = model.getClass();
       try {
           Field filed = class_my.getField(sfiled);
           System.out.println(filed.getName());
           System.out.println(filed.get(model));
       } catch (SecurityException e) {
           e.printStackTrace();
       } catch (NoSuchFieldException e) {
           e.printStackTrace();
       } catch (IllegalArgumentException e) {
           e.printStackTrace();
       } catch (IllegalAccessException e) {
           e.printStackTrace();
       }
    }
   
    /**
     *通过类名获得实体对象
     *通过属性名称获取实体对象属性值
     */
    publicstaticvoid f_1() {
       try {
           Class cla = Class.forName("RefInt.Model");
           Object o = cla.newInstance();
           String methodName = "getName";
           Method m = cla.getMethod(methodName, (Class[])null);
           System.out.println(m.invoke(o, (Object[])null));
           methodName = "getAge";
           m = cla.getMethod(methodName, (Class[])null);
           System.out.println(m.invoke(o, (Object[])null));
           methodName = "getB";
           m = cla.getMethod(methodName, (Class[])null);
           System.out.println(m.invoke(o, (Object[])null));
       } catch (ClassNotFoundException e) {
           e.printStackTrace();
       } catch (InstantiationException e) {
           e.printStackTrace();
       } catch (IllegalAccessException e) {
           e.printStackTrace();
       } catch (SecurityException e) {
           e.printStackTrace();
       } catch (NoSuchMethodException e) {
           e.printStackTrace();
       } catch (IllegalArgumentException e) {
           e.printStackTrace();
       } catch (InvocationTargetException e) {
           e.printStackTrace();
       }
    }
}
 
一般的做法是通过类Introspector来获取某个对象的BeanInfo信息,然后通过BeanInfo来获取属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的getter/setter方法,然后我们就可以通过反射机制来调用这些方法。
Intro.java
 
package RefInt;
 
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
 
publicclass Intro {
    publicstaticvoid main(String[] args) {
       Model m = new Model();
       try {
           // 从其所在位置开始停止分析的基类。stopClass 或其基类中的所有方法/属性/事件都将在分析中被忽略。
           BeanInfo beanInfor = Introspector.getBeanInfo(m.getClass(),Object.class);
           PropertyDescriptor[] p = beanInfor.getPropertyDescriptors();
           for(int i=0;i<p.length;i++){
              System.out.println(p[i].getName()+"="+
                      p[i].getReadMethod().invoke(m,(Object[])null));
            }
 
       } catch (IntrospectionException e) {
           e.printStackTrace();
       } catch (IllegalArgumentException e) {
           e.printStackTrace();
       } catch (IllegalAccessException e) {
           e.printStackTrace();
       } catch (InvocationTargetException e) {
           e.printStackTrace();
       }
    }
}
 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值