欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java通過反射來打印類的方法實(shí)現(xiàn)

 更新時(shí)間:2021年09月17日 08:38:36   作者:Zong_0915  
本文主要介紹了Java通過反射來打印類的方法實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

工作了有一段時(shí)間了,我覺得是時(shí)候去復(fù)習(xí)下Java的一些基礎(chǔ)知識(shí),因此寫下了這篇文章。平常開發(fā)過程中,前端寫的比較多,后端也不能忘!

在這里插入圖片描述

一. 案例出發(fā)

先準(zhǔn)備一個(gè)模板類:

public class User {
    public int id;
    private String name;

    public User(String name, int id) {
        this.id = id;
        this.name = name;
    }

    private User(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

開始反射

import java.lang.reflect.*;

public class Test {
    public static final String LINE = "\n";
    public static final String SPACE = "    ";

    public static void main(String[] args) throws Exception {
        Class<?> c = Class.forName("com.User");
        // Class<?> c = Test.class.getClassLoader().loadClass("com.User");
        StringBuilder sb = new StringBuilder();
        // 打印包,類名
        String packageName = c.getPackage().getName();
        sb.append("package " + packageName + ";" + LINE);
        sb.append(LINE);
        sb.append("public class " + c.getSimpleName() + "{" + LINE);
        // 打印成員變量
        Field[] declaredFields = c.getDeclaredFields();
        for (Field field : declaredFields) {
            // Field.getModifiers()返回一個(gè)int類型的數(shù)值,用于標(biāo)識(shí)public、static等標(biāo)識(shí)符
            String fieldModifier = Modifier.toString(field.getModifiers());
            // 獲取屬性類型的簡(jiǎn)要名稱
            String typeName = field.getType().getSimpleName();
            // 屬性的名稱
            String fieldName = field.getName();
            sb.append(SPACE + fieldModifier + " " + typeName + " " + fieldName + ";" + LINE);
        }
        sb.append(LINE);
        // 打印構(gòu)造
        Constructor<?>[] declaredConstructors = c.getDeclaredConstructors();
        for (Constructor<?> constructor : declaredConstructors) {
            // 構(gòu)造函數(shù)的標(biāo)識(shí)符
            String constructorModifier = Modifier.toString(constructor.getModifiers());
            sb.append(SPACE + constructorModifier + " " + c.getSimpleName() + " " + "(");
            // 打印構(gòu)造函數(shù)的參數(shù)
            printParam(sb, constructor.getParameterTypes());
        }
        // 打印方法
        Method[] methods = c.getDeclaredMethods();
        for (Method method : methods) {
            // 方法的標(biāo)識(shí)符
            String methodModifier = Modifier.toString(method.getModifiers());
            // 方法返回類型
            String returnTypeName = method.getReturnType().getSimpleName();
            // 方法名稱
            String methodName = method.getName();
            sb.append(SPACE + methodModifier + " " + returnTypeName + " " + methodName + "(");
            printParam(sb, method.getParameterTypes());
        }

        sb.append("}");
        System.out.println(sb.toString());
    }

    private static void printParam(StringBuilder sb, Class<?>[] parameterTypes2) {
        Class<?>[] parameterTypes = parameterTypes2;
        for (int i = 0; i < parameterTypes.length; i++) {
            // 參數(shù)的類型
            String simpleName = parameterTypes[i].getSimpleName();
            if (i == 0) {
                sb.append(simpleName + " args");
            } else {
                sb.append(", " + simpleName + " args");
            }
        }
        sb.append(") {" + LINE);
        sb.append(SPACE + "}" + LINE);
        sb.append(LINE);
    }
}

最終的結(jié)果如下:

在這里插入圖片描述

二. 反射方法的分析

2.1 反射的方式

代碼中我們可以發(fā)現(xiàn),這里提供了兩種基本的反射:

  • Class.forName()
  • getClassLoader().loadClass()

首先,在模板類中添加靜態(tài)塊代碼:

在這里插入圖片描述

再來運(yùn)行一下兩種反射方式的代碼:

forName

在這里插入圖片描述

getClassLoader

在這里插入圖片描述

結(jié)論如下:

初始化:通過forName方式反射的對(duì)象,會(huì)進(jìn)行初始化(會(huì)執(zhí)行靜態(tài)代碼),而通過getClassLoader方式反射的對(duì)象,是不會(huì)進(jìn)行初始化的。

2.2 修飾符的打印

如果想打印方法、屬性的修飾符,我們應(yīng)該通過Modifier類去拿到。請(qǐng)看這一行代碼:

String fieldModifier = Modifier.toString(field.getModifiers());

來看下Modifier.toString的源碼:

public static String toString(int mod) {
    StringBuilder sb = new StringBuilder();
    int len;

    if ((mod & PUBLIC) != 0)        sb.append("public ");
    if ((mod & PROTECTED) != 0)     sb.append("protected ");
    if ((mod & PRIVATE) != 0)       sb.append("private ");

    /* Canonical order */
    if ((mod & ABSTRACT) != 0)      sb.append("abstract ");
    if ((mod & STATIC) != 0)        sb.append("static ");
    if ((mod & FINAL) != 0)         sb.append("final ");
    if ((mod & TRANSIENT) != 0)     sb.append("transient ");
    if ((mod & VOLATILE) != 0)      sb.append("volatile ");
    if ((mod & SYNCHRONIZED) != 0)  sb.append("synchronized ");
    if ((mod & NATIVE) != 0)        sb.append("native ");
    if ((mod & STRICT) != 0)        sb.append("strictfp ");
    if ((mod & INTERFACE) != 0)     sb.append("interface ");

    if ((len = sb.length()) > 0)    /* trim trailing space */
        return sb.toString().substring(0, len-1);
    return "";
}

很明顯,其通過語言修飾符的類型(int類型)來做對(duì)應(yīng)的映射并返回。
案例代碼中有三塊地方都支持獲得修飾符類型:

  • field.getModifiers():字段修飾符。
  • constructor.getModifiers():構(gòu)造修飾符。
  • method.getModifiers():方法的修飾符。

2.3 getDeclaredxxx和getxxx的區(qū)別

以Field為例:

Field[] declaredFields = c.getDeclaredFields();
Field[] fields = c.getFields();

案例如下:
1.新建一個(gè)Parent類:

public class Parent {
    public String parentAddress;
    private Integer Number;
}

2.讓User類繼承Parent

在這里插入圖片描述

3.測(cè)試1:getDeclaredFields打印成員變量:

在這里插入圖片描述

4.測(cè)試2:getFields打印成員變量:

在這里插入圖片描述

兩者區(qū)別如下:

比較內(nèi)容 getDeclaredFields getFields
作用的類的范圍 僅僅限于當(dāng)前類 還可以包括父類
作用的修飾符范圍 可以獲取public和非public類型 只能獲得public類型的相關(guān)值

2.4 getSimpleName和getName有什么不同

以這行代碼為例:

String typeName = field.getType().getSimpleName();

若我將getSimpleName改為getName,看看輸出結(jié)果會(huì)有什么不同:

在這里插入圖片描述

可以發(fā)現(xiàn)gatName輸出的是這個(gè)類型的全名稱,那么對(duì)應(yīng)的getSimpleName就顧名思義,返回的是類型名稱。

對(duì)于其他的相關(guān)屬性和API,代碼的注釋都寫的比較詳細(xì)了,就不展開介紹了。

到此這篇關(guān)于Java通過反射來打印類的方法實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Java反射打印類內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java使用泛型Class實(shí)現(xiàn)消除模板代碼

    Java使用泛型Class實(shí)現(xiàn)消除模板代碼

    Class作為實(shí)現(xiàn)反射功能的類,在開發(fā)中經(jīng)常會(huì)用到,然而,當(dāng)Class遇上泛型后,事情就變得不是那么簡(jiǎn)單了,所以本文就來講講Java如何使用泛型Class實(shí)現(xiàn)消除模板代碼,需要的可以參考一下
    2023-06-06
  • 關(guān)于Spring的AnnotationAwareAspectJAutoProxyCreator類解析

    關(guān)于Spring的AnnotationAwareAspectJAutoProxyCreator類解析

    這篇文章主要介紹了關(guān)于Spring的AnnotationAwareAspectJAutoProxyCreator類解析,Spring是一個(gè)開源免費(fèi)的框架 , 容器,是一個(gè)輕量級(jí)的框架 ,需要的朋友可以參考下
    2023-05-05
  • 使用Java實(shí)現(xiàn)解析Excel公式

    使用Java實(shí)現(xiàn)解析Excel公式

    在日常工作中,我們經(jīng)常需要在Excel中使用公式對(duì)表中數(shù)據(jù)進(jìn)行計(jì)算和分析,所以本文小編主要來和大家介紹一下如何在Java中實(shí)現(xiàn)解析Excel公式,感興趣的可以了解下
    2024-02-02
  • Java多線程中的死鎖詳解

    Java多線程中的死鎖詳解

    這篇文章主要介紹了Java多線程中的死鎖詳解,死鎖是指兩個(gè)或多個(gè)線程在執(zhí)行過程中,因爭(zhēng)奪資源而造成的一種互相等待的現(xiàn)象,如果不提前預(yù)防或外界干擾,這些線程將無法執(zhí)行下去,需要的朋友可以參考下
    2023-08-08
  • Mybatis?Interceptor線程安全引發(fā)的bug問題

    Mybatis?Interceptor線程安全引發(fā)的bug問題

    這篇文章主要介紹了Mybatis?Interceptor線程安全引發(fā)的bug問題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • JavaMail實(shí)現(xiàn)郵件發(fā)送的方法

    JavaMail實(shí)現(xiàn)郵件發(fā)送的方法

    這篇文章主要介紹了JavaMail實(shí)現(xiàn)郵件發(fā)送的方法,實(shí)例分析了java實(shí)現(xiàn)郵件發(fā)送的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-04-04
  • java實(shí)現(xiàn)電腦定時(shí)關(guān)機(jī)的方法

    java實(shí)現(xiàn)電腦定時(shí)關(guān)機(jī)的方法

    這篇文章主要介紹了java實(shí)現(xiàn)電腦定時(shí)關(guān)機(jī)的方法,首先通過java注冊(cè)windows服務(wù)程序,再以一個(gè)簡(jiǎn)單的java程序?qū)崿F(xiàn)定時(shí)關(guān)機(jī)的功能,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2014-11-11
  • java?環(huán)境配置(2023年詳細(xì)教程)

    java?環(huán)境配置(2023年詳細(xì)教程)

    這篇文章首先為了完善我的知識(shí)體系,今后一些軟件的安裝教程也可能會(huì)用到想寫一個(gè)更加詳細(xì)的,因?yàn)檫@并不僅僅是寫給?IT?行業(yè)的,其它行業(yè)可能也需要配置java環(huán)境
    2023-06-06
  • Java中的HashSet集合存儲(chǔ)數(shù)據(jù)的結(jié)構(gòu)詳解

    Java中的HashSet集合存儲(chǔ)數(shù)據(jù)的結(jié)構(gòu)詳解

    這篇文章主要介紹了Java中的HashSet集合存儲(chǔ)數(shù)據(jù)的結(jié)構(gòu)詳解,數(shù)組結(jié)構(gòu)他把元素進(jìn)行分組,相同哈希值的元素是一組,鏈表/紅黑樹結(jié)構(gòu)把相同哈希值的元素鏈接到一起,存儲(chǔ)數(shù)據(jù)到集合中,先計(jì)算元素的哈希值,需要的朋友可以參考下
    2023-09-09
  • 在IntelliJ IDEA中.idea文件是什么可以刪除嗎

    在IntelliJ IDEA中.idea文件是什么可以刪除嗎

    相信有很多小伙伴,在用idea寫java代碼的時(shí)候,創(chuàng)建工程總是會(huì)出現(xiàn).idea文件,該文件也從來沒去打開使用過,那么它在我們項(xiàng)目里面,扮演什么角色,到底能不能刪除它呢?這篇文章主要介紹了在IntelliJ IDEA中.idea文件是什么可以刪除嗎,需要的朋友可以參考下
    2024-01-01

最新評(píng)論