Java反射的简单使用

内容整理自慕课网的反射课程
反射的核心,就在于Java中万物皆对象的思想。
反射可以动态记载类,调用方法,使用属性,类似于C++的DLL动态加载,但是比C++要更方便,更灵活,可以直接通过类名字符串来获取类,而如果是C++,导出类的话,需要相应的头文件来描述类信息,Java反射不需要。DLL可以动态加载,但是DLL是在编译前加载,而反射可以在运行时加载。DLL的优势是可以用不同语言去实现DLL库,而反射只能是Java的jar包。
反射是编译后的结果,可以用反射来绕开模板编程的类型检测,因为带类型的模板,对类型的检测是编译期的,类型不匹配无法通过编译,而编译后的模板对任何类型都是一样的,可以通过反射来证明(方法:通过反射获得两个不同类型模板的对象的类类型进行比较,结果为true)
以下内容没有提及数组反射(课程里没有)

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/*
 * 类(本身)是java.lang.class的对象
 * Class.forName("类的全称")
 */
public class ClassUtil {
    //获取方法
    public static void printClassMessage(Object obj){
        //要获取类的信息,首先要获取类的类类型
        Class<?> class1 = obj.getClass();//传递的是哪个子类的对象,class1就是该子类的类类型
        //获取类的名称
        System.out.println(class1.getName());
        /*
         * Method类,方法对象(方法也是一种对象)
         * 一个成员方法就是一个Method对象
         * getMethods方法获取的是所有的public 的鼾声,包括父类继承而来的
         * getDeclareMethods()获取的是所有该类自己声明的方法,不问访问权限,不包括继承来的方法
         */
        Method[] methods = class1.getMethods();
        for(int i = 0; i<methods.length; i++){
            //得到方法的返回类型,得到的是返回值的类类型
            Class<?> returnType = methods[i].getReturnType();
            System.out.print(returnType.getName() + " ");
            //得到方法的名称
            System.out.print(methods[i].getName()+"(");
            //获取参数类型-->得到的是参数的类类型
            Class<?>[] paramTypes = methods[i].getParameterTypes();
            for (Class<?> c : paramTypes) {
                System.out.print(c.getName()+", ");
            }
            System.out.println(")");
        }
    }
    //获取属性
    public static void printFieldMessage(Object obj) {
        /*
         * 成员变量也是对象
         * java.lang.reflect.Field
         * Field类封装了关于成员变量的操作
         * getFields()方法获取的是所有public的成员变量的信息
         * getDeclaredFields()获取的是该类自己声明的成员变量的信息
         */
        Class class1 = obj.getClass();
        Field[] fields = class1.getDeclaredFields();
        for (Field field : fields) {
            //得到成员变量的类类型
            Class fieldType = field.getType();
            String typeName = fieldType.getName();
            String fieldName = field.getName();
            System.out.println(typeName + " " + fieldName);
        }
    }
    /*
     * 打印构造函数的信息
     */
    public static void printConMessage(Object obj) {
        Class class1 = obj.getClass();
        /*
         * 构造函数也是对象
         * java.lang.Constructor中封装了构造函数的信息
         * getConstructors获取所有的public构造函数
         * getDeclaredConstructors获取所有的构造函数
         */
        Constructor<?>[] cs = class1.getDeclaredConstructors();
        for (Constructor<?> constructor : cs) {
            System.out.print(constructor.getName() + "(");
            Class<?>[] params = constructor.getParameterTypes();
            for(Class<?> param : params) {
                System.out.print(param.getName() + ", ");
            }
            System.out.println(")");
        }
    }
    /*
     * 
     */
    public static void useMethod() {
        //要获取print(int, int)方法
        //1 要获取一个方法就是获取类的信息,获取类的信息首先要获取类类型
        A a1 = new ClassUtil.A();
        Class<?> c = a1.getClass();
        /*
         * 2 获取方法名称和参数类比
         */
        try {
            //Method m = c.getMethod("print", new  Class<?>[]{int.class, int.class});
            Method m = c.getMethod("print", int.class, int.class);
            //Object o代表方法的返回值,如果没有返回值则是null,如果有返回值则是具体的返回值
            Object o = m.invoke(a1, new Object[]{10,20});
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public static class A{
        public void print(int a, int b) {
            System.out.println(a+b);
        }
        public void print(String a, String b) {
            System.out.println(a.toUpperCase() + "," + b.toLowerCase());
        }
    }

    public static void main(String[] args){
        try {
            //反射的动态记载和DLL的动态记载类似,但是更强大,可以通过字符串来获得类、方法、属性
            //动态加载类,在运行时刻加载
            Class<?> class1 = Class.forName(args[0]);
            //通过类类型,创建该类对象
            IClassUtil util = (IClassUtil) class1.newInstance();
            util.start();
            //String string = "";
            //printClassMessage(string);
            //printFieldMessage(string);
            //printConMessage(string);
            useMethod();
            //tttt();
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }
    public static void tttt(){
        Class<?> class1 = int.class;//int的类类型
        Class<?> class2 = String.class;
        System.out.println(class1.getName());
        System.out.println(class2.getName());
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值