反射 基本应用

public class ClassUtil {
    
    public static void printClassMethodMessage(Object obj) {
        Class c = obj.getClass();
        System.out.println(c.getName());
        
        /**
         * Method类,方法对象
         * getMethods()方法获取的是所有的public的函数,包括父类继承而来的
         * getDeclaredMethods()获取的是所有该类自己声明的方法,不问访问的权限
         */
        
        Method [] methods = c.getMethods();
        for(int i=0; i<methods.length; i++) {
            //获取方法的返回值类型的类类型
            Class returnType = methods[i].getReturnType();  //例如 String.class
            System.out.print(returnType.getName() + " ");
            //获取方法的名字
            System.out.print(methods[i].getName() + "(");
    
            //获取参数类型--->得到的是参数列表的类型的类类型
            Class [] params = methods[i].getParameterTypes();
            for(Class class1 : params) {
                System.out.print(class1.getName() + ",");
            }
            
            System.out.println(")");
            
            
    
        }
        
        
        printFieldMessage(c);
            
    }


    private static void printFieldMessage(Object object) {
        /**
         * 成员变量也是对象
         * java.lang.reflect.Field
         * Field类封装了关于成员变量的操作
         * getFields()方法获取的是所有的public的成员变量
         * getDeclaredFields() 获取的是该类自己声明的成员变量的信息
         */
        
        Class c = object.getClass();
        
        Field [] fs = c.getFields();
        for(Field field : fs) {
            //获取成员变量 的类型的类类型
            Class fieldType = field.getType();
             
            //获取成员变量类型的名字
            String typeName = fieldType.getName();
            
            //成员变量的名称
            String fieldName = field.getName();
            
            System.out.println(typeName + " " + fieldName);
        }
    }
    
    
    
    /**
     * 打印构造函数的信息
     * @param obj
     */
    
    private static void printConMessage(Object obj) {
        Class c = obj.getClass();
        
        /**
         * 构造函数也是对象
         * java.lang.Constructor 中封装了构造函数的信息
         * getConstructor 获取所有的public的构造函数
         * getDeclaredConstuctors得到所有的构造函数
         */
        
        Constructor [] cs = c.getDeclaredConstructors();
        
        for(Constructor constructor : cs) {
            System.out.print(constructor.getName() + "(");
            
            //获取构造函数的参数列表 --> 得到的是参数列表的类的类类型
            Class [] paramTypes = constructor.getParameterTypes();
            
            for(Class class1 : paramTypes) {
                System.out.print(class1.getName() + ",");
            }
            System.out.println(")");
            
        }
        
        
    }
    
    

    public static void main(String [] args) {
        String string = "qqq";
//        printClassMethodMessage(string);
//        
//        printConMessage(string);
        
        
        
        /**
         * 获取方法 名称和参数列表来决定
         * getMethod获取的是public方法
         * getDelcaredMethod自己声明的方法
         * 
         * 
         */
        A a = new A();
        Class class1 = a.getClass();
        
        try {
            Method m1 = class1.getDeclaredMethod("print");
            
            //方法如果没有返回值返回null,有返回值返回具体的返回值
            Object object = m1.invoke(a);
            System.out.println("========================");
            
            Method m2 = class1.getDeclaredMethod("print", new Class [] {int.class,int.class});
            
            Object object2 = m2.invoke(a, 10,20);
            System.out.println("========================");
            
            Method m3 = class1.getDeclaredMethod("print", String.class,String.class);
            Object object3 = m3.invoke(a, "hello","world");
            
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        

    }
    
}



class A{
    public A() {
        
    }
    
    public void print() {
        System.out.println("hello world");
    }
    
    
    public void print(int a,int b) {
        System.out.println(a+b);
    }
    
    
    public void print(String a,String b) {
        System.out.println(a.toLowerCase() + b.toUpperCase());
    }
    
}

 

 

 

反射是可以绕过编译来执行的

public class Demo {
    public static void main(String [] args) {
        ArrayList list = new ArrayList();
        
        ArrayList<String> list1 = new ArrayList<String>();
        
        list1.add("hello");
        //list1.add(20);
        
        Class c1 = list.getClass();
        Class c2 = list1.getClass();
        System.out.println(c1 == c2);
        
        //反射都是编译后的操作
        
        /**
         * c1==c2结果返回true说明编译之后集合的泛型是去泛型化的
         * Java中集合的泛型,是防止错误的输入,只在编译阶段有效
         * 绕过编译就无效了
         * 验证:通过方法的反射来操作,绕过编译
         */
        try {
            Method method = c1.getMethod("add",Object.class);
            
            method.invoke(list1, 100);
            System.out.println(list1.size());
            System.out.println(list1);
            
            /**
             * 本来list1的类型是String的 加了100后 就不能用foreach遍历了
             *
             */
        }catch (Exception e) {
            // TODO: handle exception
        }
    }
}

 

posted @ 2018-09-02 23:52  chenzquan  阅读(167)  评论(0编辑  收藏  举报