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

溫馨提示×

溫馨提示×

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

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

Java中的反射機制的基本運用

發布時間:2021-08-31 12:53:16 來源:億速云 閱讀:108 作者:chen 欄目:開發技術

這篇文章主要講解了“Java中的反射機制的基本運用”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Java中的反射機制的基本運用”吧!

目錄
  • Java中的反射機制基本運用

  • 1、什么是反射(reflect)

  • 2、反射機制提供的功能

  • 3、反射->獲取類對象

  • 4、反射->利用無參構造實例化對象

  • 5、反射->利用有參構造實例化對象

  • 6、反射->調用無參方法

  • 7、反射->調用有參方法

  • 8、反射->訪問私有方法

  • 9、反射->類加載路徑


Java中的反射機制基本運用

看完反射可以了解一下注解

注解annotation://www.5655pk.com/article/221276.htm

1、什么是反射(reflect)

反射是java的動態機制,它允許將對象的實例化,方案的調用,屬性的操作等從編碼期確定轉移到程序運行期確定。

反射能大大提高代碼的靈活度。但同時也帶來了更多的系統開銷和較慢的運行效率,因此程序不能過度依賴反射。

2、反射機制提供的功能

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

  • 在運行時構造任意一個類的對象(實例化)

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

  • 在運行時調用任意一個對象的方法——動態代理

3、反射->獲取類對象

在開始之前創建一個實體類,用于測試反射機制

package reflect_text;
/**
 * 用于測試反射機制
 *
 * @author Akio
 * @Create 2021/8/14 10:37
 */
public class Person {
    private String name = "劉瑜澄";//設置初始值
    private int age = 22;
    public Person() {//無參構造
    }
    public Person(String name, int age) {//有參構造
        this.name = name;
        this.age = age;
    }
    public void sayHello() {//無參方法
        System.out.println(name + ":使用sayHello方法");
    }
    public void sayGoodBye() {//無參方法
        System.out.println(name + ":使用sayGoodBye方法");
    }
    public void say(String info) {//有參方法
        System.out.println(name + ":" + info);
    }
    public void say(String info, int sum) {//有參方法(重載say方法)
        for (int i = 0; i < sum; i++) {
            System.out.println(name + ":" + info);
        }
    }
    private void privateMethod() {//私有方法
        System.out.println(name + ":這是一個私有方法");
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

以上這個用于測試反射的實體類創建成功后,先學習反射中是如何獲取類對象的。

反射的第一步就是要獲取操作類的類對象,即一個Class的實例,JVM中每個被加載的類有且只有一個類對象與之對應,獲取到這個類對象后我們就可以通過這個類對象來了解該類的一切信息(類名、有哪些方法、屬性等等) 以便在程序運行期間通過反射機制進行相關操作

這里介紹三種獲取類對象的方式:

  • (包名.)類名.class

Class personClass = reflect_text.Person.class;
Class intClass = int.class;

這種方式最直接,但是由于是靠硬編碼形式寫死(編譯期間已經確定),因此不夠靈活。但是需要注意,基本類型(int\double等)只能通過這種方式獲取類對象

  • Class.forName(String className)

Class personClass = Class.forName("reflect_text.Person");
Class stringClass = Class.forName("java.lang.String");

這種方式較為常用,遵循運行期綁定。

  • 類加載器ClassLoader

Class stringClass = ClassLoader.getSystemClassLoader().loadClass("java.lang.String");
Class personClass = ClassLoader.getSystemClassLoader().loadClass("reflect_text.Person");

在這一節中介紹幾個簡單的方法:

getName()
獲取類的完全限定名:包名.類名
getSimpleName()
僅僅獲取類名
getMethods()
返回一個Method數組,獲取class所表示的類的所有公開方法(包含從超類中繼承的方法)

例子:

		Scanner scanner = new Scanner(System.in);
		Class cls = Class.forName(scanner.nextLine());//運行期綁定
        String name = cls.getName();//獲取類的完全限定名:包名.類名
        System.out.println("完全限定名 = " + name);
        name = cls.getSimpleName();//僅獲取類名
        System.out.println("僅類名 = " + name);
        Method[] methods = cls.getMethods();
        for (Method m : methods) {
            System.out.print(m.getName()+"\t");
        }

4、反射->利用無參構造實例化對象

Class類中提供了一個方法newInstance()來實例化,該方法要求此類必須具有無參構造器,它是通過無參構造器實例化對象的。

		Person person = new Person();
        //1獲取要實例化的類的類對象
        Scanner scanner = new Scanner(System.in);
        System.out.println("請輸入類名:");
        Class cls = Class.forName(scanner.nextLine());
        /*
            通過Class提供的方法newInstance()來實例化
           	該方法要求此類必須具有無參構造器,它是通過無參構造器實例化對象的
         */
        Object obj = cls.newInstance();
        System.out.println("obj = " + obj);

Java中的反射機制的基本運用

5、反射->利用有參構造實例化對象

getConstructor()
//獲取無參構造器,可以利用無參構造器實例化對象,但這個方法對于使用無參構造器實例化對象可有可無
getConstructor(類對象)
//通過類對象獲取特定的構造器,該參數列表是根據特定構造器的參數列表類型來決定的,如
		getConstructor(String.class, int.class)
		即為調用Person類中兩個參數的有參構造器
		public Person(String name, int age) {//有參構造
    		this.name = name;
    		this.age = age;
		}

舉例

		//加載類對象
        Class cls = Class.forName("reflect.Person");
        //通過類對象獲取特定的構造器
        Constructor c = cls.getConstructor(String.class, int.class);
        Object o = c.newInstance("流年", 21);//實例化
        System.out.println(o);

結果可知初始值已經被修改

Java中的反射機制的基本運用

6、反射->調用無參方法

getMethod(String MethodName)
獲取類對象的MethodName方法,返回值類型為Method
invoke(Object object)
執行object對象的某方法

舉例

		//一般調用方法的做法-------------------
        Person p = new Person();//實例化對象
        p.sayHello();//調用該對象方法
        //反射機制調用方法-----------------------
        //1、實例化對象
        Class cls = Class.forName("reflect_text.Person");
        Object o = cls.newInstance();
        //2、調用o的sayHello方案
        //2.1通過Class獲取Person的sayHello方法
        Method method = cls.getMethod("sayHello");
        //2.2調用o的該方法
        method.invoke(o);//等效于一般方法中的o.sayHello()

可見兩種操作均能達到一樣的效果

Java中的反射機制的基本運用

7、反射->調用有參方法

getMethod(String MethodName, 類對象)
獲取類對象的MethodName有參方法,并傳入對應參數類型的類對象,返回值類型為Method

舉例

		//一般調用有參方法------------------------
        Person p = new Person();
        p.say("七夕快樂~");
        p.say("七夕快樂~",3);
        //反射機制調用有參方法---------------------
        Class cls = Class.forName("reflect_text.Person");
        Object o = cls.newInstance();
        //調用say(String info)方法
        Method m1 = cls.getMethod("say", String.class);
        m1.invoke(o, "春節快樂~");
        //調用say(String info, int sum)
        Method m2 = cls.getMethod("say", String.class, int.class);
        m2.invoke(o,"春節快樂~",3);

通過結果可以看到,效果都是一樣的

Java中的反射機制的基本運用

8、反射->訪問私有方法

注意:反射訪問私有的方法,但是會破壞類的封裝性

getDeclaredMethod(String MethodName)
可以僅獲取此類定義的所有方法,包含私有方法
setAccessible(boolean flag)
開啟私有方法的訪問權限

舉例

		//正常情況下,在本類中不可以訪問外部的私有方法
		//但在反射機制中可行
		Class cls = Class.forName("reflect_text.Person");
        Object o = cls.newInstance();
        Method method = cls.getDeclaredMethod("privateMethod");
        method.setAccessible(true);//打開訪問權限
        method.invoke(o);

Java中的反射機制的基本運用

9、反射->類加載路徑

加載資源時常用相對路徑,之前學習的相對路徑./由于運行環境不同,位置并非固定,因此實際開發中使用較少。
接下來介紹,在開發中常用的類加載路徑

常用的路徑通常為類的加載路徑,有兩個:

1:類對象.getResource()與當前類所處同一目錄

2:類加載器.getResource()類加載路徑,類的package定義中根包位置。

例如:有一個類:
package reflect_text;
public class WebServer{
     ……
}
在WebServer類中,當我們使用上述兩種方式獲取路徑時他們的對應位置為:
WebServer.class.getResource()
當前WebServer所在的目錄(編譯后的class文件所在目錄)
WebServer.class.getClassLoader().getResource()
則是在WebServer的包的最上級,即com包的上一級
package reflect_text;
public class ReflectDemo {
		File dir = new File(ReflectDemo.class.getResource(".").toURI());
        System.out.println("dir = " + dir);
        //dir = D:\ClassCode\JavaSE_API\out\production\JavaSE_API\reflect
        File dir2 = new File(ReflectDemo.class.getClassLoader().getResource(".").toURI());
        System.out.println("dir2 = " + dir2);
        //dir2 = D:\ClassCode\JavaSE_API\out\production\JavaSE_API
}

Java中的反射機制的基本運用

感謝各位的閱讀,以上就是“Java中的反射機制的基本運用”的內容了,經過本文的學習后,相信大家對Java中的反射機制的基本運用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

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

AI

石门县| 竹北市| 桐梓县| 县级市| 呼和浩特市| 左权县| 浙江省| 洞头县| 十堰市| 曲阳县| 喜德县| 濮阳市| 徐汇区| 弋阳县| 富蕴县| 留坝县| 巢湖市| 万全县| 萨嘎县| 南丰县| 东辽县| 宁阳县| 天等县| 宿州市| 建水县| 宁蒗| 盐山县| 娱乐| 繁昌县| 长泰县| 中江县| 张家川| 泽普县| 岐山县| 都匀市| 改则县| 田林县| 丽江市| 大厂| 普宁市| 铅山县|