Educoder–Java高級特性(第八章)- Java反射【筆記+參考代碼】

Educoder–Java高級特性(第八章)- Java反射【筆記+參考代碼】


第一關


編程要求
請仔細閱讀右側代碼,結合相關知識,在Begin-End
區域內進行代碼補充,完成三個方法getPersonClass1()、getPersonClass2()、getPersonClass3()的代碼編寫,要求分別使用三種方式獲取Person類的Class對象並返回。
注意:無需修改main()方法的輸出內容。

測試說明 平臺會對你編寫的代碼進行測試:

預期輸出:

通過Object 類中的 getClass() 獲取的 Class 對象爲:class step1.Person 通過靜態方法
Class.forName() 獲取的 Class 對象爲:class step1.Person 通過類字面常量獲取 Class
的對象爲:class step1.Person



參考代碼

package step1;
/**
 * 學員任務文件
 */
public class Reflect_stu {

    public static void main(String[] args) {
        System.out.println("通過Object 類中的 getClass() 獲取的 Class 對象爲:" + getPersonClass1());
        System.out.println("通過靜態方法 Class.forName() 獲取的 Class 對象爲:" + getPersonClass2());
        System.out.println("通過類字面常量獲取 Class 的對象爲:" + getPersonClass3());
    }
    /**
     * 通過 Object 類中的 getClass() 獲取的 Class 對象
     *
     * @return
     */
    public static Class getPersonClass1() {
        /********** Begin *********/
		Person person = new Person();
		Class c = person.getClass();
        return c;
        /********** End *********/
    }
    /**
     * 通過靜態方法 Class.forName() 獲取的 Class 對象
     * <p>
     * 注意:Person 類的全路徑爲: step1.Person
     *
     * @return
     */
    public static Class getPersonClass2() {
        /********** Begin *********/
		Class c = null;
		String classname = "step1.Person";
		try{
			c = Class.forName(classname);一個類的完整路徑加名稱
		}catch(ClassNotFoundException e){
		}
        return c;
        /********** End *********/
    }
    /**
     * 通過類字面常量獲取 Class 的對象
     *
     * @return
     */
    public static Class getPersonClass3() {
        /********** Begin *********/
		Class c = Person.class;
        return c;
        /********** End *********/
    }
}



第二關


編程要求
請仔細閱讀右側代碼,結合相關知識,在Begin-End 區域內進行代碼補充,打印Apple類的所有public
域、方法和構造器。已分別提供了方法聲明printConstructors、printFields、printMethods,請將代碼補充完整,且按照打印格式要求輸出。

提示:

Method.getReturnType()可以獲得方法的返回類型。

打印方法或域的修飾符可以調用提供的printModifiers()方法

打印方法的參數可以調用提供的printParamTypes()方法

Field的getType方法可以獲得域類型、getName方法可以獲得域的名稱

測試說明
預期輸出: private java.lang.String name; public step2.Apple(); public
step2.Apple(java.lang.String); public void setName(java.lang.String);

平臺會對你編寫的代碼進行測試。



參考代碼

package step2;

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

class Apple {
    private String name;
    public Apple(){}
    public Apple(String name){}
    public void setName(String name) {
        this.name = name;
    }
}
public class Reflect_stu {
    public static void main(String[] args) {
        // 請根據提供的 classPath 獲取 step2.Apple 的 Class 對象, 請使用 Class.forName() 方法, 注意捕獲異常
        // 通關之後,你也可以修改 clasapath 爲其他類路徑,分析某個類的能力, 例如: java.util.Date
        String classPath = "step2.Apple";
        Class clazz = null;
        /********** Begin *********/
		try{
			clazz = Class.forName(classPath);
		}catch(ClassNotFoundException e){	
		}
        /********** End *********/
        printFields(clazz);
        printConstructors(clazz);
        printMethods(clazz);
    }
  	/**
     * 請打印類的每個域,輸出格式爲:修飾符 類型 變量名;
     * @param clazz
     */
    public static void printFields(Class clazz) {
        /********** Begin *********/
		Field[] f = clazz.getDeclaredFields();
		for(Field ff:f){
			Class type = ff.getType();
			int mod = ff.getModifiers();
			System.out.print(Modifier.toString(mod)+" ");
			System.out.print(type.getName()+" ");
			System.out.println(ff.getName()+";");
		}
        /********** End *********/
    }
    /**
     * 打印構造函數,輸出格式爲:修飾符 方法名稱(參數)
     * @param clazz
     */
    public static void printConstructors(Class clazz) {
 		Constructor[] constructors = clazz.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            Class[] paramTypes = constructor.getParameterTypes();
            /********** Begin *********/
            String name = constructor.getName();
            String modifiers = Modifier.toString(constructor.getModifiers());
            if (modifiers.length() > 0) {
                System.out.print(modifiers + " ");
            }
            System.out.print(name + "(");
            /********** End *********/
            printParamTypes(paramTypes);
        }
    }
    /**
     * 請針對每個方法打印其簽名,格式爲:修飾符 返回值類型 方法名稱(參數);
     * @param clazz
     */
    public static void printMethods(Class clazz) {
        Method[] methos = clazz.getDeclaredMethods();
        for (Method method : methos) {
            Class[] paramTypes = null;
            /********** Begin *********/
			String name = method.getName();
            Class returnType = method.getReturnType();
            String modifiers = Modifier.toString(method.getModifiers());
            System.out.print(modifiers+" "+returnType.getName() + " " + name + "(");
            paramTypes = method.getParameterTypes();
            /********** End *********/
            printParamTypes(paramTypes);
        }
    }
    /**
     * 打印方法參數
     * @param paramTypes
     */
    private static void printParamTypes(Class[] paramTypes) {
        for (int j = 0; j < paramTypes.length; ++j) {
            if (j > 0) {
                System.out.print(",");
            }
            System.out.print(paramTypes[j].getName());
        }
        System.out.println(");");
    }
}



第三關


編程要求
請仔細閱讀右側代碼,結合相關知識,在Begin-End 區域內進行代碼補充,完成通用toString()方法。

提示:

快速設置訪問權限: AccessibleObject.setAccessible(fields, true);
獲得所有域:Class.getDeclaredFields()
測試說明
平臺會對你編寫的代碼進行測試。

示例:

public static void toString(Object obj) {
// 請完成代碼 } public static void main(String[] args) {
Person person = new Person(123, 19, 175);
toString(person); } 預期輸出: [weight=[value=123],age=[value=19],height=[value=175.0]]



參考代碼

package step3;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class Reflect_stu {
    public static String toString(Object obj) {
        Class cl = obj.getClass();
        String r = "";
        r += "[";
        // 請獲取所有 Field 並設置訪問權限爲 true
        /********** Begin *********/
        Field[] fields = cl.getDeclaredFields();
        AccessibleObject.setAccessible(fields, true);
        /********** End *********/
        for (Field f : fields) {
            // 此處 if,邏輯爲判斷 Field 域是否爲非靜態域
            if (!Modifier.isStatic(f.getModifiers())) {
                if (!r.endsWith("[")) r += ",";
                r += f.getName() + "=";
                try {
                    // 請獲取域的類型及值
                    /********** Begin *********/
                    Class t = f.getType();
                    Object val = f.get(obj);
                    /********** End *********/
                    // isPrimitive() 用於判斷是否爲基本數據類型,若爲基礎數據類型直接拼接,否則遞歸調用 toString 方法
                    if (t.isPrimitive()) r += val;
                    else r += toString(val);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        r += "]";
        return r;
    }
    public static void main(String[] args) {
        Person person = new Person(88, 19, 175);
        System.out.println(toString(person));
    }
}
class Person {
    public Integer weight;
    private Integer age;
    private Double height;
    public Person(Integer weight, Integer age, double height) {
        this.weight = weight;
        this.age = age;
        this.height = height;
    }
}



第四關


編程要求
請仔細閱讀右側代碼,結合相關知識,在Begin-End 區域內進行代碼補充,使用反射調用 Apple 類的
setPrice()方法,設置蘋果價格爲 14,並打印價格。接着還要用反射去調用getTotal方法獲取單價爲 20,數量 24
的總金額並打印。

測試說明
預期輸出:
14.0
480.0

平臺會對你編寫的代碼進行測試。



參考代碼

package step4;

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


public class Reflect_stu {
    public static void main(String[] args) throws InvocationTargetException {
        //使用反射調用
        Class clazz = null;
        try {
            clazz = Class.forName("step4.Apple");
            /********** Begin *********/
            Method setPriceMethod = clazz.getMethod("setPrice", double.class);
            Constructor appleConstructor = clazz.getConstructor();
            Object apple = appleConstructor.newInstance();
            setPriceMethod.invoke(apple, 14);
            Method getPriceMethod = clazz.getMethod("getPrice");
            System.out.println(getPriceMethod.invoke(apple));
            Method getTotal = clazz.getMethod("getTotal", double.class, int.class);
            System.out.println(getTotal.invoke(apple, 20, 24));
            /********** End *********/
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
class Apple {
    private double price;
    private int count;
    public Apple() {
    }
    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public double getTotal(double price, int count) {
        return price * count;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章