JAVA反射机制

java反射机制的使用

使用java反射机制可以在编译阶段去掉jar的依赖,在运行时根据类名称动态的调用类。
下面是测试过程中需要通过反射机制掉的测试类

/**********************************   
 * @Title : Test.java 
 * @Package :  
 * @Description : TODO 
 * @author : ph    
 * @date :2016年12月20日 下午9:32:01 
 * @version V1.0   
 **********************************/

public class Test {
    private String proprety = null;
    private static  int IntTest = 6;
    public String h = "hello";
    public int i = 0;

    public Test(){
        System.out.println("Test");
    }

    public Test(String ss){
        proprety = ss;
        System.out.println(proprety);
    }
    public Test(hello ss){

    }

    public void print(String re){
        System.out.println("re:"+re);
    }

    public static void printStatic(String re){
        System.out.println("re:"+re);
    }

    public static void printStatic(){
        System.out.println("int:"+IntTest);
    }

    public void printInt(int i){
        IntTest = i;
        System.out.println(IntTest);
    }

    public String getString(){
        return proprety;
    }

    public int getInt(){
        return IntTest;
    }

    class hello{

    }
}


使用示例

通过一个对象获得完整的包名和类名

Test test = new Test();
String className = test.getClass().getName();
System.out.println(className);

实例化Class类对象


        Class<?> class1 = null;
        Class<?> class2 = null;
        Class<?> class3 = null;

        try {
            // 第一种形式,java反射机制一般采用这种形式,因为这种形式可以在编辑编译的时候不需要引入Test类,即不需要import Test类,只需在运行是有jar包的依赖即可
            class1 = Class.forName("Test");

            //第二种形式,这种形式就是通过对象来获取类
            //在某些特殊情况下也可以不需要import 类,比如android中获取各种管理对象EthernetManager、WifiManager、PowerManager的对象。使用反射机制获取EthernetManager对象
            //Object obj = (Object)mContext.getSystemService(Context.ETHERNET_SERVICE);
            class2 = new Test().getClass(); 

            //第三种形式。
            class3 = Test.class;
            System.out.println("类名称   " + class1.getName());
            System.out.println("类名称   " + class2.getName());
            System.out.println("类名称   " + class3.getName());
        } catch (ClassNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

输出:

类名称   Test
类名称   Test
类名称   Test

获取一个类的父类和实现的借口


            clazz = Class.forName("Test");
            // 取得父类
            Class<?> parentClass = clazz.getSuperclass();
            System.out.println("clazz的父类为:" + parentClass.getName());
            // clazz的父类为: java.lang.Object
            // 获取所有的接口
            Class<?> intes[] = clazz.getInterfaces();
            System.out.println("clazz实现的接口有:");
            for (int i = 0; i < intes.length; i++) {
                System.out.println((i + 1) + ":" + intes[i].getName());
            }
            // clazz实现的接口有:
            // 1:java.io.Serializable

输出:

clazz的父类为:java.lang.Object
clazz实现的接口有:

查看类的构造方法的参数

Class<?> clazz;
        Object obj ;
        try {
            clazz = Class.forName("Test");

            Constructor<?> cons[] = clazz.getConstructors();
            // 查看每个构造方法需要的参数
            for (int i = 0; i < cons.length; i++) {
                Class<?> clazzs[] = cons[i].getParameterTypes();
                System.out.print("cons[" + i + "] (");
                for (int j = 0; j < clazzs.length; j++) {
                    if (j == clazzs.length - 1)
                        System.out.print(clazzs[j].getName());
                    else
                        System.out.print(clazzs[j].getName() + ",");
                }
                System.out.println(")");
            }

        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchFieldException | SecurityException | NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

输出


cons[0] (Test$hello)
cons[1] (java.lang.String)
cons[2] ()

获取类的全部方法

            Method method[] = clazz.getMethods();
            for (int i = 0; i < method.length; ++i) {
                Class<?> returnType = method[i].getReturnType();
                Class<?> para[] = method[i].getParameterTypes();
                int temp = method[i].getModifiers();
                System.out.print(Modifier.toString(temp) + " ");
                System.out.print(returnType.getName() + "  ");
                System.out.print(method[i].getName() + " ");
                System.out.print("(");
                for (int j = 0; j < para.length; ++j) {
                    System.out.print(para[j].getName() + " " + "arg" + j);
                    if (j < para.length - 1) {
                        System.out.print(",");
                    }
                }
                Class<?> exce[] = method[i].getExceptionTypes();
                if (exce.length > 0) {
                    System.out.print(") throws ");
                    for (int k = 0; k < exce.length; ++k) {
                        System.out.print(exce[k].getName() + " ");
                        if (k < exce.length - 1) {
                            System.out.print(",");
                        }
                    }
                } else {
                    System.out.print(")");
                }
                System.out.println();
            }

输出:

public void  printInt (int arg0)
public int  getInt ()
public void  print (java.lang.String arg0)
public java.lang.String  getString ()
public final void  wait () throws java.lang.InterruptedException 
public final void  wait (long arg0,int arg1) throws java.lang.InterruptedException 
public final native void  wait (long arg0) throws java.lang.InterruptedException 
public boolean  equals (java.lang.Object arg0)
public java.lang.String  toString ()
public native int  hashCode ()
public final native java.lang.Class  getClass ()
public final native void  notify ()
public final native void  notifyAll ()

获取类和该类父类的所有public变量

Class<?> clazz;
Object obj ;
        try {
            clazz = Class.forName("Test");

            Field[] fields=clazz.getFields();  //获得该类及其父类的所有字段

            //只有public的字段能解析出来
            for(Field field:fields)//利用增强for循环分解字段
            {
                int modifier=field.getModifiers();//代表访问修饰符的数字
                String strModifier=Modifier.toString(modifier);//将访问权限对应的数字还原成对应的字符串
                Class type=field.getType();//获得变量类型
                 String str=field.getName();//获得变量名
                 System.out.println(strModifier+" "+type+" "+str);// 输出结果: public class java.lang.String address 
            }       

        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchFieldException | SecurityException | NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

输出

public class java.lang.String h
public int i

创建类对象

    Class<?> clazz = null;
    Object obj = null ;
        try {
            clazz = Class.forName("Test");
            obj = clazz.newInstance();
        } catch (ClassNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

输出

Test

通过构造方法创建对象

    Class<?> clazz;
    Object obj ;
        try {
            clazz = Class.forName("Test");
            Constructor con1 = clazz.getConstructor(String.class);
            obj = con1.newInstance("dd");

        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchFieldException | SecurityException | NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

输出

dd

调用方法

try {
            clazz = Class.forName("Test");            
            obj = clazz.newInstance();

            Method method = clazz.getMethod("print",String.class);
            method.invoke(obj,"yes");//调用静态方法时把obj改为null即可

        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchFieldException | SecurityException | NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

输出

re:yes

获取类的变量值

try {
            clazz = Class.forName("Test");                           
            obj = clazz.newInstance();                              
            Field Intfiled = clazz.getDeclaredField("IntTest");
            Intfiled.setAccessible(true);
            int IntTestInt = (int) Intfiled.get(obj);//获取静态变量时把obj改为null即可
            System.out.println(IntTestInt);
        } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   

输出

6

设置变量的值

try {
            clazz = Class.forName("Test");                            
            obj = clazz.newInstance();

            // 可以直接对 private 的属性赋值 
            Field Strfield = clazz.getDeclaredField("proprety");
            Strfield.setAccessible(true); //反射使用外部类的private变量必须调用该函数关闭安全检查,并且关闭安全检查也会带来执行速度的提升,但是该函数无法对方法起作用,即private方法无通过该函数设置实现反射调用
            Strfield.set(obj, "Java反射机制");
            String propertyStr = (String) Strfield.get(obj);
            System.out.println(propertyStr);    

        } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   

输出

Java反射机制

利用java反射调用方法类

下面是本人写的一个利用类名称和方法名称即可实现反射调用的类

/** 
* @ClassName : reflectJava 
* @Description : TODO 利用java反射调用类的方法
* @author : ph
* @date : 2016年12月24日 上午9:38:12 
*  
*/
class reflectJava{
    //类
    Class<?> clazz;
    //类对象
    Object obj ;


    /** 
     * @Title: reflectJava 构造函数
     * @Description:  TODO 
     * @param name  类的全名称,包括包名    
     * @throws 名称为空时抛出IllegalArgumentException
     * @author: ph
     * @date: 2016年12月24日 上午11:11:38
     */
    public reflectJava(String name){
        if(name == null || name.length() == 0){
            throw new IllegalArgumentException("class name is null or length of name is 0");
        }
        try {
            clazz = Class.forName(name);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /** 
     * TODO:
     * @Title: printConstructor 打印所有的构造方法的参数
     * @param name  
     * @throws: 
     * @author: ph
     * @date: 2016年12月24日 上午9:05:42
     */
    public void printConstructor(){
        Constructor<?> cons[] = clazz.getConstructors();
        // 查看每个构造方法需要的参数
        for (int i = 0; i < cons.length; i++) {
            Class<?> clazzs[] = cons[i].getParameterTypes();
            System.out.print("cons[" + i + "] (");
            for (int j = 0; j < clazzs.length; j++) {
                if (j == clazzs.length - 1)
                    System.out.print(clazzs[j].getName());
                else
                    System.out.print(clazzs[j].getName() + ",");
            }
            System.out.println(")");
        }
    }

    /** 
     * TODO:
     * @Title: createInstance 使用参数类型为paramClass、值为paramObject的构造方法创建对象
     * @param paramClass
     * @param paramObject  
     * @throws: 
     * @author: ph
     * @date: 2016年12月24日 上午9:11:21
     */
    public void createInstance(Class<?> paramClass,Object paramObject){

        try {
            Constructor con1 = clazz.getConstructor(paramClass);
            obj = con1.newInstance(paramObject);
        } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /** 
     * TODO:创建类对象,必须在类含有无参构造方法的条件下才能调用
     * @Title: createInstance   
     * @throws: 
     * @author: ph
     * @date: 2016年12月24日 下午12:05:08
     */
    public void createInstance(){
            try {
                obj = clazz.newInstance();
            } catch (InstantiationException | IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    }

    /** 
     * TODO:
     * @Title: printFileds   打印该类及其父类的所有字段
     * @throws: 
     * @author: ph
     * @date: 2016年12月24日 上午9:19:57
     */
    public void printFileds(){

        Field[] fields=clazz.getFields();  //获得该类及其父类的所有字段

        //只有public的字段能解析出来
        for(Field field:fields)//利用增强for循环分解字段
        {
            int modifier=field.getModifiers();//代表访问修饰符的数字
            String strModifier=Modifier.toString(modifier);//将访问权限对应的数字还原成对应的字符串
            Class type=field.getType();//获得变量类型
             String str=field.getName();//获得变量名
             System.out.println(strModifier+" "+type+" "+str);// 输出结果: public class java.lang.String address 
        }      
    }

    /** 
     * TODO:  调用类的动态方法,只能调用public方法
     * @Title: runMethod 
     * @param methodName 方法名称,用字符串表示
     * @param paramClass 方法所需参数的类型,如String,则为String.class
     * @param paramObject 方法所需参数的值,需与类型对应
     * @return  放回方法执行的结果,需要转化为相应的类型值,如int a = (int)runMethod(...);
     * @throws: 
     * @author: ph
     * @date: 2016年12月24日 上午9:31:09
     */
    public Object runMethod(String methodName,Class<?> paramClass,Object paramObject){
        Object reObject = null;
        if(obj == null){
            return reObject;
        }
        try {
            Method method ;
            if(paramClass == null){
                method = clazz.getMethod(methodName);
                reObject = method.invoke(obj);
            }else{
                method = clazz.getMethod(methodName,paramClass);
                reObject = method.invoke(obj,paramObject);
            }
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return reObject;
    }

    /** 
     * TODO: 调用类的静态方法,参数和返回值和runMethod一样,只能调用public方法
     * @Title: runStateMethod 
     * @param methodName
     * @param paramClass
     * @param paramObject
     * @return  
     * @throws: 
     * @author: ph
     * @date: 2016年12月24日 上午9:34:22
     */
    public Object runStaticMethod(String methodName,Class<?> paramClass,Object paramObject){
        Object reObject = null;
        try {
            Method method ;
            if(paramClass == null){
                method = clazz.getMethod(methodName);
                reObject = method.invoke(null);
            }else{
                method = clazz.getMethod(methodName,paramClass);
                reObject = method.invoke(null,paramObject);
            }
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return reObject;
    }

    /** 
     * TODO:设置对象变量的值,private和public都可以赋值
     * @Title: setField 
     * @param fieldName 变量的名称,字符表示
     * @param fieldClass 变量的类型
     * @param fieldObject  变量的值
     * @throws: 
     * @author: ph
     * @date: 2016年12月24日 上午9:46:21
     */
    public void setField(String fieldName,Class<?> fieldClass,Object fieldObject){
        if(obj == null){
            return ;
        }
        // 可以直接对 private 的属性赋值
        try {
            Field Strfield = clazz.getDeclaredField(fieldName);
            Strfield.setAccessible(true); // 反射使用外部类的private变量必须调用该函数关闭安全检查,并且关闭安全检查也会带来执行速度的提升,但是该函数无法对方法起作用,即private方法无通过该函数设置实现反射调用
            Strfield.set(obj, fieldObject);
        } catch (NoSuchFieldException | SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }


    public void setStaticField(String fieldName,Class<?> fieldClass,Object fieldObject){
        // 可以直接对 private 的属性赋值
        try {
            Field Strfield = clazz.getDeclaredField(fieldName);
            Strfield.setAccessible(true); // 反射使用外部类的private变量必须调用该函数关闭安全检查,并且关闭安全检查也会带来执行速度的提升,但是该函数无法对方法起作用,即private方法无通过该函数设置实现反射调用
            Strfield.set(null, fieldObject);
        } catch (NoSuchFieldException | SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }

    /** 
     * TODO: 获取变量的值 ,private和public都可以获取到
     * @Title: getField 
     * @param fieldName 变量的名称
     * @return  返回变量的值,需要根据相应的类型转换,如String field = (String)getField("fil");
     * @throws: 
     * @author: ph
     * @date: 2016年12月24日 上午9:48:21
     */
    public Object getField(String fieldName){
        Object reObject = null;
        if(obj == null){
            return reObject;
        }
        try {
            Field Strfield = clazz.getDeclaredField(fieldName);
            Strfield.setAccessible(true);//反射使用外部类的private变量必须调用该函数关闭安全检查,并且关闭安全检查也会带来执行速度的提升,但是该函数无法对方法起作用,即private方法无通过该函数设置实现反射调用 
            reObject = Strfield.get(obj);
        } catch (NoSuchFieldException | SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return reObject;
    }


    public Object getStaticFiled(String fieldName){
        Object reObject = null;
        try {
            Field Strfield = clazz.getDeclaredField(fieldName);
            Strfield.setAccessible(true); //反射使用外部类的private变量必须调用该函数关闭安全检查,并且关闭安全检查也会带来执行速度的提升,但是该函数无法对方法起作用,即private方法无通过该函数设置实现反射调用
            reObject = Strfield.get(null);
        } catch (NoSuchFieldException | SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return reObject;
    }
}

调用实例:

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;


/**********************************   
 * @Title : TestForJava.java 
 * @Package :  
 * @Description : TODO 
 * @author : ph    
 * @date :2016年12月20日 下午9:31:32 
 * @version V1.0   
 **********************************/

public class TestForJava {
    /** 
     * TODO:
     * @Title: main 
     * @param args  
     * @throws: 
     * @author: ph
     * @date: 2016年12月20日 下午9:33:58
     */
    public static void main(String[] args) {

        reflectJava ref = new reflectJava("Test");

        //打印构造方法和变量
        ref.printConstructor();
        ref.printFileds();

        //设置和获取静态变量
        ref.setStaticField("IntTest", int.class, 5);
        System.out.println(ref.getStaticFiled("IntTest"));

        //调用静态方法
        ref.runStaticMethod("printStatic", String.class, "yes");
        ref.runStaticMethod("printStatic", null, null);
        //使用无参构造方法创建对象
        ref.createInstance();

        //使用有参构造方法创建对象
        ref.createInstance(String.class, "create");

        //设置动态变量,前提是先要调用createInstance创建类对象
        ref.setField("proprety", String.class, "string field");
        System.out.println(ref.getField("proprety"));

        //调用动态方法,前提是先要调用createInstance创建类对象
        String result =(String)ref.runMethod("getString", null, null);
        System.out.println(result);
        ref.runMethod("printInt", int.class, 3);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值