真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

java反射機(jī)制原理介紹

本篇內(nèi)容主要講解“java反射機(jī)制原理介紹”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“java反射機(jī)制原理介紹”吧!

創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比哈密網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式哈密網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋哈密地區(qū)。費(fèi)用合理售后完善,10年實(shí)體公司更值得信賴。

?

1反射機(jī)制是什么

反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法和屬性;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱為java語言的反射機(jī)制。

在面向?qū)ο蟮氖澜缋铮f事萬物皆對(duì)象.在java語言里,靜態(tài)的成員,普通數(shù)據(jù)類型是不是對(duì)象呢?

類又是誰的對(duì)象呢?

首先類是對(duì)象,類是java.lang.Class類的實(shí)例對(duì)象.

新創(chuàng)建一個(gè)Foo類

Foo這個(gè)類也是一個(gè)實(shí)例對(duì)象,是Class類的實(shí)例對(duì)象,這個(gè)對(duì)象在官網(wǎng)被稱為(class type).

反射是java程序開發(fā)語言的特性之一,它允許運(yùn)行中的java程序獲取自身的信息,并且可以操作類或者對(duì)象內(nèi)部的屬性.

?反射的核心是JVM在運(yùn)行時(shí)才動(dòng)態(tài)加載類或調(diào)用方法/訪問屬性,它不需要事先(寫代碼的時(shí)候或編譯期)知道運(yùn)行對(duì)象是誰。

了解反射其實(shí)需要了解JVM,不過一般的資料不會(huì)在這一部分講到JVM,畢竟學(xué)習(xí)也是要從淺入深的.

2反射機(jī)制能做什么

反射機(jī)制主要提供了以下功能: 

  • 在運(yùn)行時(shí)判斷任意一個(gè)對(duì)象所屬的類;

  • 在運(yùn)行時(shí)構(gòu)造任意一個(gè)類的對(duì)象;

  • 在運(yùn)行時(shí)判斷任意一個(gè)類所具有的成員變量和方法;

  • 在運(yùn)行時(shí)調(diào)用任意一個(gè)對(duì)象的方法;

  • 生成動(dòng)態(tài)代理。

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

在Eclipse,當(dāng)我們輸入一個(gè)點(diǎn)的時(shí)候(比如 a.)   編譯器就會(huì)自動(dòng)列出它的屬性和方法,這里就會(huì)用到反射

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

java的反射機(jī)制的實(shí)現(xiàn)要借助于4個(gè)類: class,Constructor,Field,Method;

通過一個(gè)對(duì)象獲得完整的包名和類名

package cn.xins08.boke;

public class TestReflect {

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

    }

}

實(shí)例化Class對(duì)象:

實(shí)現(xiàn)反射機(jī)制獲取類有三種方法:

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開發(fā)中常用此方法加載數(shù)據(jù)驅(qū)動(dòng))
        class1 = Class.forName("cn.xins08.boke.TestReflect");
      //第三種方式:java中任何一個(gè)對(duì)象都有g(shù)etClass方法
        class2 = new TestReflect().getClass();
        
        //第三種方式j(luò)ava中任何一個(gè)對(duì)象都有class屬性
        class3 = TestReflect.class;
        System.out.println("類名稱: " + class1.getName());
        System.out.println("類名稱: " + class2.getName());
        System.out.println("類名稱: " + class3.getName());
        // 打印結(jié)果:
        /*
         * 類名稱: cn.xins08.boke.TestReflect 類名稱: cn.xins08.boke.TestReflect 類名稱:
         * cn.xins08.boke.TestReflect
         */
    }
}

獲取一個(gè)對(duì)象的父類與實(shí)現(xiàn)的接口:

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實(shí)現(xiàn)的接口有:");
                for (int i = 0; i < intes.length; i++) {
                    System.out.println((i + 1) + ":" + intes[i].getName());
                }
                // clazz實(shí)現(xiàn)的接口有:
                // 1:java.io.Serializable
        
    }
}

創(chuàng)建實(shí)例:

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

(1)使用Class對(duì)象的newInstance()方法來創(chuàng)建Class對(duì)象對(duì)應(yīng)類的實(shí)例。

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

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

     區(qū)別在于創(chuàng)建對(duì)象的方式不一樣,前者是使用類加載機(jī)制,那么為什么會(huì)有兩種創(chuàng)建對(duì)象方式?這個(gè)就要從可伸縮、可擴(kuò)展,可重用等軟件思想上解釋了。

newInstance: 弱類型。低效率。只能調(diào)用無參構(gòu)造。
new: 強(qiáng)類型。相對(duì)高效。能調(diào)用任何public構(gòu)造。
newInstance()是實(shí)現(xiàn)IOC、反射、面對(duì)接口編程 和 依賴倒置 等技術(shù)方法的必然選擇,new 只能實(shí)現(xiàn)具體類的實(shí)例化,不適合于接口編程。

(2)先通過Class對(duì)象獲取指定的Constructor對(duì)象,再調(diào)用Constructor對(duì)象的newInstance()方法來創(chuàng)建實(shí)例。這種方法可以用指定的構(gòu)造器構(gòu)造類的實(shí)例。

// 獲取String所對(duì)應(yīng)的Class對(duì)象
        Class c = String.class;
        // 獲取String類帶一個(gè)String參數(shù)的構(gòu)造器
        Constructor constructor = c.getConstructor(String.class);
        // 根據(jù)構(gòu)造器創(chuàng)建實(shí)例
        Object obj = constructor.newInstance("23333");
        System.out.println(obj);

注意事項(xiàng):反射會(huì)額外的消耗一定的系統(tǒng)資源,如果不需要?jiǎng)討B(tài)的創(chuàng)建一個(gè)對(duì)象,那么就不需要用反射

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

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();

    }

}
//返回的結(jié)果是"吃蘋果"

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

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的類類型,做強(qiáng)制類型轉(zhuǎn)換 
    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();

    }

}

這時(shí)候我們發(fā)現(xiàn)即使增加幾個(gè)接口的子類,工廠類照樣可以完成對(duì)象的實(shí)例化操作,可以對(duì)應(yīng)所有的變化.

    到目前為止你已經(jīng)會(huì)了最基本的反射使用了,在學(xué)習(xí)Spring之前先講這些,等學(xué)習(xí)了Spring的依賴注入,反轉(zhuǎn)控制之后,相信會(huì)對(duì)反射有更好的理解.

到此,相信大家對(duì)“java反射機(jī)制原理介紹”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!


新聞標(biāo)題:java反射機(jī)制原理介紹
網(wǎng)址分享:http://weahome.cn/article/ghssgh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部