最近开发游戏服务器数据接口时
来源:未知 点击: 发布时间:2017-06-09 15:51

最近开发游戏服务器数据接口时,碰巧遇上要用大量反射,综合一下网上反射的文章,简单实现反射,呵呵呵……

 

Java提供了一套机制来动态执行方法和构造方法,以及数组操作等,这套机制就叫??反射。

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。


Java反射机制主要提供了以下功能:

在运行时判断任意一个对象所属的类; 在运行时构造任意一个类的对象; 在运行时判断任意一个类所具有的成员变量和方法; 在运行时调用任意一个对象的方法; 生成动态代理。

Java 反射所需要的类并不多,主要有 java.lang.Class 类和 java.lang,易博亚洲.reflect 包中的 Field 、 Constructor 、 Method 、 Array 类,下面对这些类做一个简单的说明。

 

1.          Class 类: Class 类的实例表示正在运行的 Java 应用程序中的类和接口。

2.          Field 类:提供有关类或接口的属性的信息,以及对它的动态访问权限。反射的字段可能是一个类属性或实例属性,简单的理解可以把它看成一个封装反射类的属性的 类。

3.          Constructor 类:提供关于类的单个构造方法的信息以及对它的访问权限。这个类和 Field 类不同, Field 类封装了反射类的属性,而 Constructor 类则封装了反射类的构造方法。

4.          Method 类:提供关于类或接口上单独某个方法的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。这个类不难理解,它是用来封装反射类方法的一个 类。

5.          Array 类:提供了动态创建数组和访问数组的静态方法。该类中的所有方法都是静态方法。  

 

其中, Class 类是 Java 反射的起源,针对任何一个你想探勘的类,只有先为它产生一个 Class 类的对象,接下来才能通过 Class 对象获取其他想要的信息。接下来就重点介绍一下 Class 类。


1. 得到某个对象的属性
public Object getProperty(Object owner, String fieldName) throws Exception {
        Class ownerClass = owner.getClass(); //得到该对象的Class。
        Field field = ownerClass.getField(fieldName); //通过Class得到类声明的属性。
        Object property = field.get(owner); //通过对象得到该属性的实例,如果这个属性是非公有的,这里会报IllegalAccessException
        return property;
}

 
2. 得到某个类的静态属性
public Object getStaticProperty(String className, String fieldName) throws Exception {
        Class ownerClass = Class.forName(className); //首先得到这个类的Class
        Field field = ownerClass.getField(fieldName); //和上面一样,通过Class得到类声明的属性
        Object property = field.get(ownerClass); //这里和上面有些不同,因为该属性是静态的,所以直接从类的Class里取
        return property;
}

 


3. 执行某对象的方法

public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception {
        Class ownerClass = owner.getClass(); //首先还是必须得到这个对象的Class
 ,易博亚洲;       Class[] argsClass = new Class[args.length]; //配置参数的Class数组,作为寻找Method的条件
        for (int i = 0, j = args.length; i < j; i++) {
                argsClass[i] = args[i].getClass();
        }
        Method method = ownerClass.getMethod(methodName, argsClass); //通过Method名和参数的Class数组得到要执行的Method
        return method.invoke(owner, args);//执行该Method,invoke方法的参数是执行这个方法的对象,和参数数组。

          //返回值是Object,也既是该方法的返回值。
}

 

 

4. 执行某个类的静态方法 
public Object invokeStaticMethod(String className, String methodName, Object[] args) throws Exception {
        Class ownerClass = Class.forName(className);//首先还是必须得到这个对象的Class
        Class[] argsClass = new Class[args.length];//配置参数的Class数组,作为寻找Method的条件
        for (int i = 0, j = args.length; i < j; i++) {
                argsClass[i] = args[i].getClass();
        }
        Method method = ownerClass.getMethod(methodName, argsClass);//通过Method名和参数的Class数组得到要执行的Method
        return method.invoke(null, args);//invoke的一个参数是null,因为这是静态方法,不需要借助实例运行

 

基本的原理和实例3相同,不同点是最后一行,invoke的一个参数是null,因为这是静态方法,不需要借助实例运行。

5. 新建实例

public Object newInstance(String className, Object[] args) throws Exception {
        Class newoneClass = Class.forName(className);  //第一步,得到要构造的实例的Class
        Class[] argsClass = new Class[args.length]; //得到参数的Class数组
        for (int i = 0, j = args.length; i < j; i++) {
                argsClass[i] = args[i].getClass();
        }
        Constructor cons = newoneClass.getConstructor(argsClass); //得到构造子
        return cons.newInstance(args); //根据参数生成实例
}

 

public Object newInstance(String className) throws Exception {
    ,易博亚洲;    Class newoneClass = Class.forName(className); //第一步,得到要构造的实例的Class
        return cons.newInstance(); //不用参数,直接使用newInstance()实现
}


6. 判断是否为某个类的实例
public boolean isInstance(Object obj, Class cls) {
        return cls.isInstance(obj);
}

 

7. 得到数组中的某个元素
public Object getByArray(Object array, int index) {
        return Array.get(array,index);
}