1. 程式人生 > >反射 基本應用

反射 基本應用

權限 void tolower try ons int 防止 getmethod class

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
        }
    }
}

反射 基本應用