最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java上乘武功入門--反射

 更新時(shí)間:2021年07月19日 08:51:25   作者:二當(dāng)家的白帽子  
反射是Java的一種機(jī)制,一般也叫做反射機(jī)制,本文會(huì)講反射機(jī)制是什么和怎么使用,喜歡的朋友可以觀看一下,希望能給你帶來(lái)幫助

先來(lái)看一段魔法吧

public class Test {
    private static void changeStrValue(String str, char[] value) {
    	// 只要執(zhí)行魔法代碼就可以達(dá)到下面的效果
        // 施展魔法的代碼稍后揭秘
    }
    public static void main(String[] args) {
        changeStrValue("abc", new char[]{'d','e','f'});
        String abc = "abc";
        System.out.println("abc");
        System.out.println(abc);
        System.out.println("abc".equals(abc));
    }
}

在這里插入圖片描述

二當(dāng)家的第一次看到這個(gè)執(zhí)行結(jié)果覺(jué)得很有意思。明明應(yīng)該是"abc"怎么就變成了"def"呢?

反射機(jī)制是個(gè)什么玩意兒?

Java的反射(reflection)機(jī)制是指在程序的運(yùn)行狀態(tài)中,可以構(gòu)造任意一個(gè)類的對(duì)象,可以了解任意一個(gè)對(duì)象所屬的類,可以了解任意一個(gè)類的成員變量和方法,可以調(diào)用任意一個(gè)對(duì)象的屬性和方法。這種動(dòng)態(tài)獲取程序信息以及動(dòng)態(tài)調(diào)用對(duì)象的功能稱為Java語(yǔ)言的反射機(jī)制。反射被視為動(dòng)態(tài)語(yǔ)言的關(guān)鍵。

以上就是百科的解釋??赡苡悬c(diǎn)抽象,接著看二當(dāng)家的給你秀起來(lái)解釋一下。

構(gòu)造任意一個(gè)類的對(duì)象

一般情況下,我們?nèi)绻胍獎(jiǎng)?chuàng)建一個(gè)類的對(duì)象,應(yīng)該要用到new關(guān)鍵字。但是像spring這樣的框架,我們只需要配置類名,就可以得到類的實(shí)例。他是怎么做到的呢?

import java.util.List;
public class Test {
    /**
     * 根據(jù)類名取得類實(shí)例
     * @author 二當(dāng)家的白帽子 https://le-yi.blog.csdn.net/
     * @param className
     * @param <T>
     * @return
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws ClassNotFoundException
     */
    public static <T> T getInstance(String className) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        Class<T> clazz = (Class<T>) Class.forName(className);
        return clazz.newInstance();
    }
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        List<String> list = getInstance("java.util.ArrayList");
        list.add("abc");
        list.add("def");
        for (String v : list) {
            System.out.println(v);
        }
    }
}

類名可以在程序運(yùn)行中從配置文件獲取,甚至是從網(wǎng)絡(luò)獲取,然后動(dòng)態(tài)創(chuàng)建一個(gè)類的實(shí)例。

了解任意一個(gè)對(duì)象所屬的類

import java.util.ArrayList;
public class Test {
     /**
     * 打印對(duì)象的類名
     * @author 二當(dāng)家的白帽子 https://le-yi.blog.csdn.net/
     * @param o
     */
    public static void printClass(Object o) {
        System.out.printf(o.getClass().getName());
    }
    public static void main(String[] args) {
        printClass(new ArrayList<>());
    }
}

在這里插入圖片描述

了解任意一個(gè)類的成員變量和方法

我們一般要使用一個(gè)類,先要知道有什么方法和屬性,先了解,后使用。但是像spring那樣的框架為什么可以為我們自動(dòng)注入呢?他怎么知道我們一個(gè)對(duì)象里有什么屬性呢?

import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test {
    /**
     * 打印類的屬性
     * @author 二當(dāng)家的白帽子 https://le-yi.blog.csdn.net/
     * @param clazz
     */
    public static void printFields(Class clazz) {
        System.out.println(clazz.getName() + "包含如下屬性:");
        for (Field f : clazz.getDeclaredFields()) {
            System.out.println(f);
        }
    }
    /**
     * 打印類的方法
     * @author 二當(dāng)家的白帽子 https://le-yi.blog.csdn.net/
     * @param clazz
     */
    public static void printMethods(Class clazz) {
        System.out.println(clazz.getName() + "包含如下方法:");
        for (Method m : clazz.getDeclaredMethods()) {
            System.out.println(m);
        }
    }
    public static void main(String[] args) {
        printFields(MyClass.class);
        printMethods(MyClass.class);
    }
}
class MyClass {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

在這里插入圖片描述

調(diào)用任意一個(gè)對(duì)象的屬性和方法

像spring這樣的框架,即使一個(gè)屬性是私有屬性并且沒(méi)有set方法,一樣可以注入。

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test {
    /**
     * 調(diào)用一個(gè)對(duì)象的方法
     * @author 二當(dāng)家的白帽子 https://le-yi.blog.csdn.net/
     * @param o
     * @param methodName
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    public static void callMethod(Object o, String methodName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Method m = o.getClass().getDeclaredMethod(methodName);
        m.setAccessible(true);
        m.invoke(o);
    }
    /**
     * 修改一個(gè)對(duì)象的屬性
     * @author 二當(dāng)家的白帽子 https://le-yi.blog.csdn.net/
     * @param o
     * @param fieldName
     * @param value
     * @throws IllegalAccessException
     */
    public static void changeFieldValue(Object o, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException {
        Field f = o.getClass().getDeclaredField(fieldName);
        f.setAccessible(true);
        f.set(o, value);
    }
    public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException, NoSuchFieldException {
        MyClass o = new MyClass();
        // 修改任意屬性,即使是私有的
        changeFieldValue(o, "name", "二當(dāng)家的白帽子");
        // 調(diào)用任意方法,即使是私有的
        callMethod(o, "printName");
    }
}
class MyClass {
	// 私有屬性,只可以調(diào)用set方法修改
    private String name;
    private void printName() {
        // 私有方法,只有本類自己的實(shí)例可以調(diào)用
        System.out.println("My name is " + name);
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

在這里插入圖片描述

魔法揭秘

是時(shí)候揭秘魔法的真面目了,沒(méi)錯(cuò),也是利用了反射。

import java.lang.reflect.Field;
public class Test {
    /**
     * 修改字符串內(nèi)部的值
     * @author 二當(dāng)家的白帽子 https://le-yi.blog.csdn.net/
     * @param str
     * @param value
     */
    private static void changeStrValue(String str, char[] value) {
        try {
            Field f = str.getClass().getDeclaredField("value");
            f.setAccessible(true);
            f.set(str, value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        changeStrValue("abc", new char[]{'d','e','f'});
        // 這里的"abc"字符串和上面調(diào)用changeStrValue的參數(shù)"abc"會(huì)指向同一塊內(nèi)存
        String abc = "abc";
        System.out.println("abc");
        System.out.println(abc);
        System.out.println("abc".equals(abc));
    }
}

要理解這段代碼,除了反射機(jī)制還需要了解java對(duì)于字符串的處理。"字符串常量池"已經(jīng)超出本文的范圍,是另一個(gè)話題,本文就不多說(shuō)了。

原本字符串內(nèi)容是"abc",我們正常情況下無(wú)法修改這個(gè)內(nèi)容,因?yàn)镾tring是不變類。但是反射大法卻可以打破一切禁忌。

總結(jié)

一般的程序可能用不到寫反射的代碼。但是像spring這樣的框架,如果沒(méi)有反射,我真的想不出如何實(shí)現(xiàn)呢。哪怕永遠(yuǎn)不需要用反射,了解機(jī)制對(duì)我們都有著莫大的好處。

本篇文章就到這里了,希望能給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • JSON--List集合轉(zhuǎn)換成JSON對(duì)象詳解

    JSON--List集合轉(zhuǎn)換成JSON對(duì)象詳解

    這篇文章主要介紹了List集合轉(zhuǎn)換成JSON對(duì)象,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。
    2017-01-01
  • springboot?ConfigurationProperties的綁定源碼示例解析

    springboot?ConfigurationProperties的綁定源碼示例解析

    這篇文章主要為大家介紹了springboot?ConfigurationProperties的綁定源碼示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • Java?Collections.sort()實(shí)現(xiàn)List排序的默認(rèn)方法和自定義方法

    Java?Collections.sort()實(shí)現(xiàn)List排序的默認(rèn)方法和自定義方法

    這篇文章主要介紹了Java?Collections.sort()實(shí)現(xiàn)List排序的默認(rèn)方法和自定義方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2017-06-06
  • Java中classpath的基本概念和配置方法詳析

    Java中classpath的基本概念和配置方法詳析

    這篇文章主要介紹了Java中的classpath概念,包括其基本概念、設(shè)置方法以及在Java應(yīng)用中的作用,在IDE中的配置也進(jìn)行了詳細(xì)說(shuō)明,并提到了一些通用注意事項(xiàng),需要的朋友可以參考下
    2025-02-02
  • JAVA?IDEA項(xiàng)目打包為jar包的步驟詳解

    JAVA?IDEA項(xiàng)目打包為jar包的步驟詳解

    在Java開(kāi)發(fā)中我們通常會(huì)將我們的項(xiàng)目打包成可執(zhí)行的Jar包,以便于在其他環(huán)境中部署和運(yùn)行,下面這篇文章主要給大家介紹了關(guān)于JAVA?IDEA項(xiàng)目打包為jar包的相關(guān)資料,需要的朋友可以參考下
    2024-08-08
  • Java棧和基礎(chǔ)隊(duì)列的實(shí)現(xiàn)詳解

    Java棧和基礎(chǔ)隊(duì)列的實(shí)現(xiàn)詳解

    這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)中的棧與隊(duì)列,在Java的時(shí)候,對(duì)于棧與隊(duì)列的應(yīng)用需要熟練的掌握,這樣才能夠確保Java學(xué)習(xí)時(shí)候能夠有扎實(shí)的基礎(chǔ)能力。本文小編就來(lái)詳細(xì)說(shuō)說(shuō)Java中的棧與隊(duì)列,需要的朋友可以參考一下
    2022-02-02
  • LinkedList學(xué)習(xí)示例模擬堆棧與隊(duì)列數(shù)據(jù)結(jié)構(gòu)

    LinkedList學(xué)習(xí)示例模擬堆棧與隊(duì)列數(shù)據(jù)結(jié)構(gòu)

    這篇文章主要介紹了LinkedList學(xué)習(xí)示例,模擬一個(gè)堆棧與隊(duì)列數(shù)據(jù)結(jié)構(gòu),大家參考使用吧
    2014-01-01
  • 詳解Java的線程狀態(tài)

    詳解Java的線程狀態(tài)

    本文主要為大家詳細(xì)介紹一下Java的線程狀態(tài),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)有一定的幫助,感興趣的小伙伴可以跟隨小編學(xué)習(xí)一下
    2022-11-11
  • 淺析Java中如何實(shí)現(xiàn)線程之間通信

    淺析Java中如何實(shí)現(xiàn)線程之間通信

    本篇文章主要介紹了淺析Java中如何實(shí)現(xiàn)線程之間通信。針對(duì) Java 的線程間通信進(jìn)行了大致的講解,有興趣的可以了解一下
    2017-04-04
  • 解決SpringBoot運(yùn)行Test時(shí)報(bào)錯(cuò):SpringBoot Unable to find

    解決SpringBoot運(yùn)行Test時(shí)報(bào)錯(cuò):SpringBoot Unable to find

    這篇文章主要介紹了SpringBoot運(yùn)行Test時(shí)報(bào)錯(cuò):SpringBoot Unable to find a @SpringBootConfiguration,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10

最新評(píng)論

镇巴县| 沭阳县| 元江| 凤阳县| 即墨市| 和顺县| 民乐县| 康乐县| 吴忠市| 望江县| 玉田县| 海口市| 长子县| 凤翔县| 宜黄县| 四会市| 道真| 延吉市| 丹凤县| 阿尔山市| 溧水县| 宁明县| 基隆市| 凌云县| 类乌齐县| 深水埗区| 刚察县| 综艺| 兰西县| 偃师市| 临澧县| 绥宁县| 平顶山市| 浏阳市| 肥西县| 莆田市| 临邑县| 锦州市| 景泰县| 凤翔县| 麻城市|