Java反射机制

作者: im_panlei | 来源:发表于2016-01-29 01:47 被阅读183次

    万事万物皆对象

    在java中类也是对象,是Class类的实例对象,这个对象称为该类的类类型

    例如:现在有个类叫SmartTalk

     class SmartTalk {
    
       public String name;
       public int age;
    
       public void sayHello() {
           System.out.println("hello");
       }
    
       private void sayHello(String hello){
           System.out.println(hello);
       }
     }
    

    如何去获取这个类的类类型呢?有以下三种方式:

    public class ClassDemo {
        public static void main(String[] args) {
            //第一种方式,说明每一个类都默认含有一个静态的class对象
            Class c1 = SmartTalk.class;
            //第二种方式
            SmartTalk smartTalk = new SmartTalk();
            Class c2 = smartTalk.getClass();
            System.out.println(c1 == c2);//true
            //第三种方式
            Class c3 = null;
            try {
                c3 = Class.forName("包名+SmartTalk");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            System.out.println(c2 == c3);//true
            //通过类类型获得实例对象
            try {
                SmartTalk smartTalk1 = (SmartTalk) c1.newInstance();
                smartTalk1.sayHello();//hello
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
    

    获取了类类型有什么用处呢?我们可以获取一个类的所有信息包括类名,属性,方法等,可以通过Field,Method等类来实现。

    public class ClassUtil {
        /**
         * 打印该类的信息,通过反射机制,我们可以获得一个类的信息
         *
         * @param object 该类对象所属类的信息
         */
        public static void printClassInfo(Object object) {
            //要获取类的信息,首先获取类的类类型
            Class c = object.getClass();
            c.getName();//类的全称(包括包名)
            System.out.println(c.getName());
    
            Field[] fields = c.getDeclaredFields();//获取所有该类自己声明的属性(实例域)
            for (Field filed : fields) {
                Class fc = filed.getType();//获取属性类型的类类型
                System.out.print(fc.getName()+" ");
                System.out.println(filed.getName());
            }
    
    
            Method[] methods = c.getDeclaredMethods();//获取所有的public方法,包括父类继承而来的
            c.getDeclaredFields();//获取所有该类自己声明的方法,不管访问去权限,不包含父类的方法
            for (Method m : methods) {
                Class returnType = m.getReturnType();//得到方法返回值类型的类类型
                System.out.print(returnType.getName() + " ");
                m.getName();//获取方法名称
                System.out.print(m.getName() + "(");
                Class[] params = m.getParameterTypes();//获取方法参数列表中的类的类类型
                for (Class param : params) {
                    System.out.print(param.getName() + ",");
                }
                System.out.println(")");
            }
        }
    }
    

    当然了,我们还可以获得一个属性的或者方法的访问权限,通过getModifiers()方法。还有许多特性可以在官方文档里查阅。下面介绍如何通过反射进行方法调用:

    public static void main(String[] args) {
            ...
    
            Class c1 = SmartTalk.class;//获得类类型
            try {
                /**
                 * 访问共有方法
                 */
                Method method1 = c1.getMethod("sayHello"/*方法名*/);//获得Method对象,或者使用c1.getDeclaredMethod("sayHello")
                method1.invoke(c1.newInstance()/*类对象*/);//方法调用
                /**
                 * 访问非共有方法
                 */
                Method method2 = c1.getDeclaredMethod("sayHello"/*方法名*/,String.class/*参数类类型*/);//不可使用getMethod(获取不到对象,抛出method not found)
                method2.setAccessible(true);//调用私有方法时需要设置为true
                method2.invoke(c1.newInstance()/*类对象*/,"hello,SmartTalk"/*参数对象*/);//方法调用
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    

    通过代码里的注释,很清楚的展示出了反射机制方法调用的基本流程,java反射机制可以获取正在运行的java对象,改变其属性和行为,非常的灵活。这是一篇反射机制的学习笔记,如有错误,感谢批评指正。

    相关文章

      网友评论

        本文标题:Java反射机制

        本文链接:https://www.haomeiwen.com/subject/tcejkttx.html