天天看點

大資料必學Java基礎(八十八):通過案例和概念體會反射的好處

文章目錄

​​通過案例和概念體會反射的好處​​

​​一、通過案例體會反射的好處​​

​​二、通過概念再體會反射​​

通過案例和概念體會反射的好處

一、通過案例體會反射的好處

案例:美團外賣  -->  付款  -->  要麼用微信支付,要麼用支付寶支付

package com.lanson.test01;
//接口的制定方:美團外賣
public interface Mtwm {
    //線上支付功能:
    void payOnline();
}

public class WeChat implements Mtwm{
    @Override
    public void payOnline() {
        //具體實作微信支付的功能:
        System.out.println("我已經點了外賣,正在使用微信支付");
    }
}

public class AliPay implements Mtwm {
    @Override
    public void payOnline() {
        //具體的支付寶支付:
        System.out.println("我已經點了外賣,我正在使用支付寶進行支付");
    }
}

public class BankCard implements Mtwm{
    @Override
    public void payOnline() {
        System.out.println("我已經定了外賣,我正在用招商銀行信用卡支付");
    }
}      

測試類:

package com.lanson.test01;

public class Test {
    public static void main(String[] args) {
        //定義一個字元串,用來模拟前台的支付方式:
        String str = "微信";
        if("微信".equals(str)){//str.equals("微信")---?避免空指針異常
            //微信支付:
            //new WeChat().payOnline();
            pay(new WeChat());
        }

        if("支付寶".equals(str)){
            //支付寶支付:
            //new AliPay().payOnline();
            pay(new AliPay());
        }

        if("招商銀行".equals(str)){
            pay(new BankCard());
        }
    }
    //微信支付
    public static void pay(WeChat wc){
        wc.payOnline();
    }
    //支付寶支付
    public static void pay(AliPay ap){
        ap.payOnline();
    }

    //招商銀行支付
    public static void pay(BankCard bc){
        bc.payOnline();
    }
}      

為了提高代碼的擴充性  -->  面向對象多态特性

package com.lanson.test01;

public class Test {
    public static void main(String[] args) {
        //定義一個字元串,用來模拟前台的支付方式:
        String str = "微信";
        if("微信".equals(str)){//str.equals("微信")---?避免空指針異常
            //微信支付:
            pay(new WeChat());
        }

        if("支付寶".equals(str)){
            //支付寶支付:
            pay(new AliPay());
        }

        if("招商銀行".equals(str)){
            pay(new BankCard());
        }
    }
    //方法形參是接口,具體傳入的是接口的實作類的對象---》多态的一種形式
    public static void pay(Mtwm m){
        m.payOnline();
    }
}      

多态确實可以提高代碼的擴充性,但是擴充性沒有達到最好。

怎麼沒有達到最好,上面的分支,還是需要手動的删除或者添加。

解決辦法:反射機制

利用反射實作上述功能

package com.lanson.test01;

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

public class Demo {
    public static void main(String[] args) throws Exception {
        //定義一個字元串,用來模拟前台的支付方式:
        String str = "com.lanson.test01.AliPay";  //字元串:實際上:就是微信類的全限定路徑

        //下面的代碼就是利用反射:
        Class  cls = Class.forName(str);//cls-->Class類具體的對象--》AliPay位元組碼資訊
        Object o = cls.newInstance();
        Method method = cls.getMethod("payOnline");
        method.invoke(o);
    }
}      

二、通過概念再體會反射

JAVA反射機制是在運作狀态中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象, 都能夠調用它的任意方法和屬性;這種動态擷取資訊以及動态調用對象方法的功能稱為java語言的反射機制。

在編譯後産生位元組碼檔案的時候,類加載器子系統通過二進制位元組流,負責從檔案系統加載class檔案。

在執行程式(java.exe)時候,将位元組碼檔案讀入JVM中這個過程叫做類的加載。然後在記憶體中對應建立一個java.lang.Class對象,這個對象會被放入位元組碼資訊中,這個Class對象,就對應加載那個位元組碼資訊,這個對象将被作為程式通路方法區中的這個類的各種資料的外部接口。

是以我們可以通過這個對象看到類的結構,這個對象就好像是一面鏡子,透過鏡子看到類的各種資訊,我們形象的稱之為反射。

這種“看透”class的能力(the ability of the program to examine itself)被稱為introspection(内省、内觀、檢討)。Reflection和introspection是常被并提的兩個術語。

說明:在運作期間,如果我們要産生某個類的對象,Java虛拟機(JVM)會檢查該類型的Class對象是否已被加載。

如果沒有被加載,JVM會根據類的名稱找到.class檔案并加載它。一旦某個類型的Class對象已被加載到記憶體,就可以用它來産生該類型的所有對象。

擴充知識:

動态語言vs靜态語言

1、動态語言

是一類在運作時可以改變其結構的語言:例如新的函數、對象、甚至代碼可以被引進,已有的函數可以被删除或是其他結構上的變化。通俗點說就是在運作時代碼可以根據某些條件改變自身結構。

主要動态語言:Object-C、 C#、JavaScript、 PHP、 Python、 Erlang 等

2、靜态語言

與動态語言相對應的,運作時結構不可變的語言就是靜态語言。

如Java、C、 C++等

  • 📢部落格首頁
  • 📢歡迎點贊 👍 收藏 ⭐留言 📝 如有錯誤敬請指正!
  • 📢本文由 Lansonli 原創
  • 📢停下休息的時候不要忘了别人還在奔跑,希望大家抓緊時間學習,全力奔赴更美好的生活✨