Java 反射

1、Java反射獲取某個類的全部屬性

Java反射獲取某個類的全部屬性,步驟所用方法如下:

    1. forName():返回給定串名相應(yīng)的Class對象。
    1. getDeclaredFields():返回當(dāng)前Class對象表示的類或接口的所有的類成員。
    1. getFields():返回當(dāng)前Class對象表示的類或接口的所有可訪問的公有類成員。
    1. getModifiers():返回該類或接口的Java語言修改器代碼,是 public、protect 還是 private。
    1. getName():返回Class對象表示的類型(類、接口、數(shù)組或基類型)的完整路徑名字符串。
package com.example.demo.Sub;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class TestReflect implements Serializable {
    private static final long serialVersionUID = -2862585049955236662L;
    public static void main(String[] args) throws Exception {
        Class<?> clazz = Class.forName(TestReflect.class.getName());
        System.out.println("===============本類屬性===============");
        // 取得本類的全部屬性
        Field[] field = clazz.getDeclaredFields();
        for (int i = 0; i < field.length; i++) {
            // 權(quán)限修飾符
            int mo = field[i].getModifiers();
            String priv = Modifier.toString(mo);
            // 屬性類型
            Class<?> type = field[i].getType();
            System.out.println(priv + " " + type.getName() + " " + field[i].getName() + ";");
        }
         
        System.out.println("==========實現(xiàn)的接口或者父類的屬性==========");
        // 取得實現(xiàn)的接口或者父類的屬性
        Field[] filed1 = clazz.getFields();
        for (int j = 0; j < filed1.length; j++) {
            // 權(quán)限修飾符
            int mo = filed1[j].getModifiers();
            String priv = Modifier.toString(mo);
            // 屬性類型
            Class<?> type = filed1[j].getType();
            System.out.println(priv + " " + type.getName() + " " + filed1[j].getName() + ";");
        }
    }
}

2、Java通過反射機制實例化一個類的對象

    1. newInstance():創(chuàng)建類的新實例。
    1. getConstructors():返回當(dāng)前Class對象表示的類的所有公有構(gòu)造函數(shù)數(shù)組。
package com.example.demo.Sub;

import java.lang.reflect.Constructor;
public class TestReflect {
    public static void main(String[] args) throws Exception {
        Class<?> class1 = null;
        class1 = Class.forName(User.class.getName());
        // 第一種方法,實例化默認(rèn)構(gòu)造方法,調(diào)用set賦值
        User user = (User) class1.newInstance();
        user.setAge(20);
        user.setName("Rollen");
        System.out.println(user);
        // 結(jié)果 User [age=20, name=Rollen]
        // 第二種方法 取得全部的構(gòu)造函數(shù) 使用構(gòu)造函數(shù)賦值
        Constructor<?> cons[] = class1.getConstructors();
        // 查看每個構(gòu)造方法需要的參數(shù)
        for (int i = 0; i < cons.length; i++) {
            Class<?> clazzs[] = cons[i].getParameterTypes();
            System.out.print("cons[" + i + "] (");
            for (int j = 0; j < clazzs.length; j++) {
                if (j == clazzs.length - 1)
                    System.out.print(clazzs[j].getName());
                else
                    System.out.print(clazzs[j].getName() + ",");
            }
            System.out.println(")");
        }
        // 結(jié)果
        // cons[0] (java.lang.String)
        // cons[1] (int,java.lang.String)
        // cons[2] ()
        user = (User) cons[0].newInstance("Rollen");
        System.out.println(user);
        // 結(jié)果 User [age=0, name=Rollen]
        user = (User) cons[1].newInstance(20, "Rollen");
        System.out.println(user);
        // 結(jié)果 User [age=20, name=Rollen]
    }
}
class User {
    private int age;
    private String name;
    public User() {
        super();
    }
    public User(String name) {
        super();
        this.name = name;
    }
    public User(int age, String name) {
        super();
        this.age = age;
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "User [age=" + age + ", name=" + name + "]";
    }
}

3、Java通過反射機制獲取某個類的全部方法

    1. getMethods():返回當(dāng)前Class對象表示的類或接口的所有公有成員方法對象數(shù)組,包括已聲明的和從父類繼承的方法。
package com.example.demo.Sub;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class TestReflect implements Serializable {

   public static void main(String[] args) throws Exception {
       Class<?> clazz = Class.forName(TestReflect.class.getName());
       Method method[] = clazz.getMethods();
       for (int i = 0; i < method.length; ++i) {
           Class<?> returnType = method[i].getReturnType();
           Class<?> para[] = method[i].getParameterTypes();
           int temp = method[i].getModifiers();
           System.out.print(Modifier.toString(temp) + " ");
           System.out.print(returnType.getName() + "  ");
           System.out.print(method[i].getName() + " ");
           System.out.print("(");
           for (int j = 0; j < para.length; ++j) {
               System.out.print(para[j].getName() + " " + "arg" + j);
               if (j < para.length - 1) {
                   System.out.print(",");
               }
           }
           Class<?> exce[] = method[i].getExceptionTypes();
           if (exce.length > 0) {
               System.out.print(") throws ");
               for (int k = 0; k < exce.length; ++k) {
                   System.out.print(exce[k].getName() + " ");
                   if (k < exce.length - 1) {
                       System.out.print(",");
                   }
               }
           } else {
               System.out.print(")");
           }
           System.out.println();
       }
   }
}

4、Java通過反射機制調(diào)用某個類的方法


import java.lang.reflect.Method;
public class TestReflect {

    public static void main(String[] args) throws Exception {
        Class<?> clazz = Class.forName(TestReflect.class.getName());
        Method method = clazz.getMethod("reflect1");
        method.invoke(clazz.newInstance());

        Method method1 = clazz.getMethod("reflect2", Integer.class, String.class);
        method1.invoke(clazz.newInstance(), 18, "徐蜀");
    }


    public void reflect1() {
        System.out.println("Java 反射機制 - 調(diào)用某個類的方法1.");
    }
    public void reflect2(Integer age, String name) {
        System.out.println("Java 反射機制 - 調(diào)用某個類的方法2.");
        System.out.println("age -> " + age + ". name -> " + name);
    }
}

5、Java通過反射機制操作某個類的屬性

import java.lang.reflect.Field;
public class TestReflect {

   private String field = null;

   public static void main(String[] args) throws Exception {
       Class<?> clazz = Class.forName(TestReflect.class.getName());
       Object object = clazz.newInstance();

       Field field = clazz.getDeclaredField("field");
       field.set(object, "Java反射機制,射你一臉");
       field.setAccessible(true);
       System.out.println(field.get(object));
   }
}

6、實戰(zhàn)

假設(shè)這樣一種場景,前端就想要幾個字段,你一股腦把所有字段都返回了。
然后前端找你來理論:勞資就只要幾個字段,都返回干嘛,就給我這幾個字段就行。
你回復(fù):這些都放在一個類里返回的,總不能我重新給你寫個類吧。難道你要特定的字段,我就寫個類給你?
然后你們打起來了?。。?!

比如簡單的方式是你用一個 map,然后 key 是 name,value 是屬性的值,你一個個遍歷,然后邊寫邊罵:傻逼前端,搞的勞資代碼寫那么垃圾,艸!?。。ㄍ蝗幌氲?graphql 的好處了。。。)

高級的方式當(dāng)然不會這么 der,直接反射即可:
FilterUtil.java

package com.example.demo.Sub.reflectPratice;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author xushu
 * @create 1/20/21 9:32 PM
 * @desc
 */
public class FilterUtil {


    /**
     * 單個類的情況
     * @param object
     * @param names
     * @return
     * @throws IllegalAccessException
     */
    public static Map<String, Object> getFilterClass(Object object, List<String> names) throws IllegalAccessException {
        Class<?> clazz = object.getClass();

        Map<String, Object> map = new HashMap<>();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            if(names.contains(field.getName())){
                map.put(field.getName(), field.get(object));
            }
        }
        return map;
    }


    /**
     * list 的情況
     * @param objectList
     * @param names
     * @return
     * @throws IllegalAccessException
     */
    public static List<Map<String, Object>> getFilterListClass(List<Object> objectList, List<String> names) throws IllegalAccessException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (Object o : objectList) {
            list.add(getFilterClass(o, names));
        }

        return list;
    }
}

PersonXushu.java

package com.example.demo.Sub.reflectPratice;

import java.util.ArrayList;
import java.util.List;

/**
 * @author xushu
 * @create 1/20/21 9:28 PM
 * @desc
 */
public class PersonXushu {

    private String name;
    private String address;
    private Integer age;
    private String favorite;

    public PersonXushu() {
    }

    public PersonXushu(String name, String address, Integer age, String favorite) {
        this.name = name;
        this.address = address;
        this.age = age;
        this.favorite = favorite;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getFavorite() {
        return favorite;
    }

    public void setFavorite(String favorite) {
        this.favorite = favorite;
    }


    public static List<PersonXushu> getList(){
        List<PersonXushu> list = new ArrayList<>();
        PersonXushu personXushu1 = new PersonXushu("xushu", "hangzhou", 18, "get money");
        PersonXushu personXushu2 = new PersonXushu("xushu", "hangzhou", 18, "get money");
        PersonXushu personXushu3 = new PersonXushu("xushu", "hangzhou", 18, "get money");
        PersonXushu personXushu4 = new PersonXushu("xushu", "hangzhou", 18, "get money");

        list.add(personXushu1);
        list.add(personXushu2);
        list.add(personXushu3);
        list.add(personXushu4);
        return list;
    }
}

Reflect.java

package com.example.demo.Sub.reflectPratice;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author xushu
 * @create 1/20/21 9:29 PM
 * @desc
 */
public class Reflect {


    public static void main(String[] args) throws IllegalAccessException {
        // 單個類
        PersonXushu personXushu1 = new PersonXushu("xushu", "hangzhou", 18, "get money");
        Map<String, Object> map = FilterUtil.getFilterClass(personXushu1, Arrays.asList("name", "address", "favorite"));
        for (String s : map.keySet()) {
            System.out.println("名稱為:" + s + ",值為" + map.get(s));
        }


        // list 情況
        List list = PersonXushu.getList();
        List<Map<String, Object>> listMap = FilterUtil.getFilterListClass(list, Arrays.asList("name", "address", "favorite"));
        for (Map<String, Object> objectMap : listMap) {
            for (String s : objectMap.keySet()) {
                System.out.println("名稱為:" + s + ",值為" + objectMap.get(s));
            }
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容