中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java反射機制原理介紹

發布時間:2021-08-18 17:53:55 來源:億速云 閱讀:136 作者:chen 欄目:大數據

本篇內容主要講解“java反射機制原理介紹”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“java反射機制原理介紹”吧!

?

1反射機制是什么

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

在面向對象的世界里,萬事萬物皆對象.在java語言里,靜態的成員,普通數據類型是不是對象呢?

類又是誰的對象呢?

首先類是對象,類是java.lang.Class類的實例對象.

新創建一個Foo類

Foo這個類也是一個實例對象,是Class類的實例對象,這個對象在官網被稱為(class type).

反射是java程序開發語言的特性之一,它允許運行中的java程序獲取自身的信息,并且可以操作類或者對象內部的屬性.

?反射的核心是JVM在運行時才動態加載類或調用方法/訪問屬性,它不需要事先(寫代碼的時候或編譯期)知道運行對象是誰。

了解反射其實需要了解JVM,不過一般的資料不會在這一部分講到JVM,畢竟學習也是要從淺入深的.

2反射機制能做什么

反射機制主要提供了以下功能: 

  • 在運行時判斷任意一個對象所屬的類;

  • 在運行時構造任意一個類的對象;

  • 在運行時判斷任意一個類所具有的成員變量和方法;

  • 在運行時調用任意一個對象的方法;

  • 生成動態代理。

注意;是運行時獲取而不是編譯時獲取.其實很多時候我們直接用eclipse寫代碼忽略了編譯的過程

在Eclipse,當我們輸入一個點的時候(比如 a.)   編譯器就會自動列出它的屬性和方法,這里就會用到反射

3反射機制的相關API (在這里只說反射機制五種功能的前兩種)

java的反射機制的實現要借助于4個類: class,Constructor,Field,Method;

通過一個對象獲得完整的包名和類名

package cn.xins08.boke;

public class TestReflect {

    public static void main(String[] args) {
        TestReflect testReflect = new TestReflect();
        System.out.println(testReflect.getClass().getName());
        // 結果:cn.xins08.boke.TestReflect

    }

}

實例化Class對象:

實現反射機制獲取類有三種方法:

package cn.xins08.boke;

public class TestReflect {
    public static void main(String[] args) throws Exception {

        Class<?> class1 = null;
        Class<?> class2 = null;
        Class<?> class3 = null;
        //第一種方式(在JDBC開發中常用此方法加載數據驅動)
        class1 = Class.forName("cn.xins08.boke.TestReflect");
      //第三種方式:java中任何一個對象都有getClass方法
        class2 = new TestReflect().getClass();
        
        //第三種方式java中任何一個對象都有class屬性
        class3 = TestReflect.class;
        System.out.println("類名稱: " + class1.getName());
        System.out.println("類名稱: " + class2.getName());
        System.out.println("類名稱: " + class3.getName());
        // 打印結果:
        /*
         * 類名稱: cn.xins08.boke.TestReflect 類名稱: cn.xins08.boke.TestReflect 類名稱:
         * cn.xins08.boke.TestReflect
         */
    }
}

獲取一個對象的父類與實現的接口:

package cn.xins08.boke;

import java.io.Serializable;

public class TestReflect implements Serializable {
     private static final long serialVersionUID = -2862585049955236662L;
    public static void main(String[] args) throws Exception {
         
            
                Class<?> clazz = Class.forName("cn.xins08.boke.TestReflect");
                // 取得父類
                Class<?> parentClass = clazz.getSuperclass();
                System.out.println("clazz的父類為:" + parentClass.getName());
                // clazz的父類為: java.lang.Object
                // 獲取所有的接口
                Class<?> intes[] = clazz.getInterfaces();
                System.out.println("clazz實現的接口有:");
                for (int i = 0; i < intes.length; i++) {
                    System.out.println((i + 1) + ":" + intes[i].getName());
                }
                // clazz實現的接口有:
                // 1:java.io.Serializable
        
    }
}

創建實例:

通過反射來生成對象主要有兩種方式:

(1)使用Class對象的newInstance()方法來創建Class對象對應類的實例。

Class<?> c = String.class;
Object str = c.newInstance();

    初始化一個類,生成一個實例的時候,new與newInstance() 有什么區別?

     區別在于創建對象的方式不一樣,前者是使用類加載機制,那么為什么會有兩種創建對象方式?這個就要從可伸縮、可擴展,可重用等軟件思想上解釋了。

newInstance: 弱類型。低效率。只能調用無參構造。
new: 強類型。相對高效。能調用任何public構造。
newInstance()是實現IOC、反射、面對接口編程 和 依賴倒置 等技術方法的必然選擇,new 只能實現具體類的實例化,不適合于接口編程。

(2)先通過Class對象獲取指定的Constructor對象,再調用Constructor對象的newInstance()方法來創建實例。這種方法可以用指定的構造器構造類的實例。

// 獲取String所對應的Class對象
        Class<?> c = String.class;
        // 獲取String類帶一個String參數的構造器
        Constructor constructor = c.getConstructor(String.class);
        // 根據構造器創建實例
        Object obj = constructor.newInstance("23333");
        System.out.println(obj);

注意事項:反射會額外的消耗一定的系統資源,如果不需要動態的創建一個對象,那么就不需要用反射

在文章的最后我們討論下工廠模式:

package cn.xins08.boke;

public interface Fruit {
public void eat();

}
package cn.xins08.boke;

public class Apple implements Fruit{
    public void eat(){
        System.out.println("吃蘋果");
    }

    

}
package cn.xins08.boke;

public class Factory {
public static Fruit getInstance(String className){
    if("apple".equals(className)){
        return new Apple();
    }
    return null;
}
}
package cn.xins08.boke;

public class FactoryDemo {

    public static void main(String[] args) {
        Fruit f = Factory.getInstance("apple");
        f.eat();

    }

}
//返回的結果是"吃蘋果"

這種是一個最簡單的工廠設計模式,但是有一個很大的問題是,如果現在接口的子類增加了,那么工廠類肯定需要改.而造成這個問題的病因就是new,如果變成反射機制就不一樣了.反射的實例化對象只需要包.類就可以了.

package cn.xins08.boke;

public interface Fruit {
public void eat();

}
package cn.xins08.boke;

public class Orange implements Fruit{
    public void eat(){
        System.out.println("吃橘子");
    }

    

}
package cn.xins08.boke;

public class Apple implements Fruit{
    public void eat(){
        System.out.println("吃蘋果");
    }

    }
package cn.xins08.boke;

public class Factory {
public static Fruit getInstance(String className){
   Fruit fruit = null;
try{
   //這里是Fruit的類類型,做強制類型轉換 
    fruit = (Fruit) Class.forName(className).newInstance() ;
    } catch(Exception e) {
       e.printStackTrace();
   }
       return  f ;
       }
  }



}
package cn.xins08.boke;

public class FactoryDemo {

    public static void main(String[] args) {
        Fruit f = Factory.getInstance("cn.xins08.boke.Apple");
        f.eat();

    }

}

這時候我們發現即使增加幾個接口的子類,工廠類照樣可以完成對象的實例化操作,可以對應所有的變化.

    到目前為止你已經會了最基本的反射使用了,在學習Spring之前先講這些,等學習了Spring的依賴注入,反轉控制之后,相信會對反射有更好的理解.

到此,相信大家對“java反射機制原理介紹”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

永寿县| 苍溪县| 汨罗市| 衡水市| 石屏县| 海林市| 阿尔山市| 明光市| 阜康市| 长葛市| 保山市| 额济纳旗| 贵州省| 夏津县| 巴塘县| 陵川县| 含山县| 湛江市| 凌云县| 尖扎县| 房产| 延寿县| 新绛县| 尉犁县| 石景山区| 彰化县| 丁青县| 翁源县| 杭锦后旗| 玉树县| 微山县| 门头沟区| 广汉市| 德化县| 惠水县| 香港| 尤溪县| 武功县| 翁牛特旗| 望城县| 德庆县|