簡述java的反射機制及其應用,java的反射機制的應用

本文目錄一覽:

java課程分享Java的反射機制

Java反射機制是一個非常強大的功能,在很多大型項目比如Spring,Mybatis都可以看見反射的身影。通過反射機制我們可以在運行期間獲取對象的類型信息,利用這一特性我們可以實現工廠模式和代理模式等設計模式,同時也可以解決Java泛型擦除等令人苦惱的問題。下面java課程就從實際應用的角度出發,來應用一下Java的反射機制。

反射基礎

p.s:本文需要讀者對反射機制的API有一定程度的了解,如果之前沒有接觸過的話,建議先看一下官方文檔的QuickStart。

在應用反射機制之前,首先我們先來看一下如何獲取一個對象對應的反射類Class,在Java中我們有三種方法可以獲取一個對象的反射類。

通過getClass方法

在Java中,每一個Object都有一個getClass方法,通過getClass方法我們可以獲取到這個對象對應的反射類:

Strings=”ziwenxie”;

Class?c=s.getClass();

通過forName方法

我們也可以調用Class類的靜態方法forName:

Class?c=Class.forName(“java.lang.String”);

使用.class

或者我們也可以直接使用.class:

Class?c=String.class;

獲取類型信息

在文章開頭我們就提到反射的一大好處就是可以允許我們在運行期間獲取對象的類型信息,下面我們通過一個例子來具體看一下。

首先我們在typeinfo.interfacea包下面新建一個介面A:

packagetypeinfo.interfacea;

publicinterfaceA{voidf();}

接著我們在typeinfo.packageaccess包下面新建一個介面C,介面C繼承自介面A,並且我們還另外創建了幾個用於測試的方法,注意下面幾個方法的許可權都是不同的。

什麼是JAVA的反射機制?有什麼作用?

現在學習Java的平台有很多,B站或者是騰訊課堂都是可以的,我們在B站分享了很多經典的Java視頻教程,都是開源的,你可以去看看。

java中反射原理,和應用

1、反射的原理,即是jvm通過位元組碼class文件,生成相應的對象。

就像正常生成一個對象一樣,都是來源於位元組碼class文件,

之所以叫反射,只是因為他不像正常的對象聲明,如A a=new A()的方式。

2、反射在框架中的應用太廣,只舉一個典型的例子,即Spring中Bean的注入。

bean總是先聲明class路徑,然後依次生成就可以了。

再試下吧。

java中的反射機制是什麼?有什麼作用呢?求解,謝謝。

Java反射機制詳解

1. 反射機制是什麼

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

2. 反射機制能做什麼

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

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

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

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

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

生成動態代理。

3. 反射機制的相關API

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

package net.xsoftlab.baike;

public class TestReflect {

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

        TestReflect testReflect = new TestReflect();

        System.out.println(testReflect.getClass().getName());

        // 結果 net.xsoftlab.baike.TestReflect

    }

}

實例化Class類對象

package net.xsoftlab.baike;

public class TestReflect {

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

        Class? class1 = null;

        Class? class2 = null;

        Class? class3 = null;

        // 一般採用這種形式

        class1 = Class.forName(“net.xsoftlab.baike.TestReflect”);

        class2 = new TestReflect().getClass();

        class3 = TestReflect.class;

        System.out.println(“類名稱   ” + class1.getName());

        System.out.println(“類名稱   ” + class2.getName());

        System.out.println(“類名稱   ” + class3.getName());

    }

}

獲取一個對象的父類與實現的介面

package net.xsoftlab.baike;

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(“net.xsoftlab.baike.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

    }

}

獲取某個類中的全部構造函數 – 詳見下例

通過反射機制實例化一個類的對象

package net.xsoftlab.baike;

import java.lang.reflect.Constructor;

public class TestReflect {

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

        Class? class1 = null;

        class1 = Class.forName(“net.xsoftlab.baike.User”);

        // 第一種方法,實例化默認構造方法,調用set賦值

        User user = (User) class1.newInstance();

        user.setAge(20);

        user.setName(“Rollen”);

        System.out.println(user);

        // 結果 User [age=20, name=Rollen]

        // 第二種方法 取得全部的構造函數 使用構造函數賦值

        Constructor? cons[] = class1.getConstructors();

        // 查看每個構造方法需要的參數

        for (int i = 0; i  cons.length; i++) {

            Class? clazzs[] = cons[i].getParameterTypes();

            System.out.print(“cons[” + i + “] (“);

            for (int j = 0; j  clazzs.length; j++) {

                if (j == clazzs.length – 1)

                    System.out.print(clazzs[j].getName());

                else

                    System.out.print(clazzs[j].getName() + “,”);

            }

            System.out.println(“)”);

        }

        // 結果

        // cons[0] (java.lang.String)

        // cons[1] (int,java.lang.String)

        // cons[2] ()

        user = (User) cons[0].newInstance(“Rollen”);

        System.out.println(user);

        // 結果 User [age=0, name=Rollen]

        user = (User) cons[1].newInstance(20, “Rollen”);

        System.out.println(user);

        // 結果 User [age=20, name=Rollen]

    }

}

class User {

    private int age;

    private String name;

    public User() {

        super();

    }

    public User(String name) {

        super();

        this.name = name;

    }

    public User(int age, String name) {

        super();

        this.age = age;

        this.name = name;

    }

    public int getAge() {

        return age;

    }

    public void setAge(int age) {

        this.age = age;

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    @Override

    public String toString() {

        return “User [age=” + age + “, name=” + name + “]”;

    }

}

獲取某個類的全部屬性

package net.xsoftlab.baike;

import java.io.Serializable;

import java.lang.reflect.Field;

import java.lang.reflect.Modifier;

public class TestReflect implements Serializable {

    private static final long serialVersionUID = -2862585049955236662L;

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

        Class? clazz = Class.forName(“net.xsoftlab.baike.TestReflect”);

        System.out.println(“===============本類屬性===============”);

        // 取得本類的全部屬性

        Field[] field = clazz.getDeclaredFields();

        for (int i = 0; i  field.length; i++) {

            // 許可權修飾符

            int mo = field[i].getModifiers();

            String priv = Modifier.toString(mo);

            // 屬性類型

            Class? type = field[i].getType();

            System.out.println(priv + ” ” + type.getName() + ” ” + field[i].getName() + “;”);

        }

         

        System.out.println(“==========實現的介面或者父類的屬性==========”);

        // 取得實現的介面或者父類的屬性

        Field[] filed1 = clazz.getFields();

        for (int j = 0; j  filed1.length; j++) {

            // 許可權修飾符

            int mo = filed1[j].getModifiers();

            String priv = Modifier.toString(mo);

            // 屬性類型

            Class? type = filed1[j].getType();

            System.out.println(priv + ” ” + type.getName() + ” ” + filed1[j].getName() + “;”);

        }

    }

}

通過反射機制調用某個類的方法

package net.xsoftlab.baike;

import java.lang.reflect.Method;

public class TestReflect {

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

        Class? clazz = Class.forName(“net.xsoftlab.baike.TestReflect”);

        // 調用TestReflect類中的reflect1方法

        Method method = clazz.getMethod(“reflect1”);

        method.invoke(clazz.newInstance());

        // Java 反射機制 – 調用某個類的方法1.

        // 調用TestReflect的reflect2方法

        method = clazz.getMethod(“reflect2”, int.class, String.class);

        method.invoke(clazz.newInstance(), 20, “張三”);

        // Java 反射機制 – 調用某個類的方法2.

        // age – 20. name – 張三

    }

    public void reflect1() {

        System.out.println(“Java 反射機制 – 調用某個類的方法1.”);

    }

    public void reflect2(int age, String name) {

        System.out.println(“Java 反射機制 – 調用某個類的方法2.”);

        System.out.println(“age – ” + age + “. name – ” + name);

    }

}

通過反射機制操作某個類的屬性

package net.xsoftlab.baike;

import java.lang.reflect.Field;

public class TestReflect {

    private String proprety = null;

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

        Class? clazz = Class.forName(“net.xsoftlab.baike.TestReflect”);

        Object obj = clazz.newInstance();

        // 可以直接對 private 的屬性賦值

        Field field = clazz.getDeclaredField(“proprety”);

        field.setAccessible(true);

        field.set(obj, “Java反射機制”);

        System.out.println(field.get(obj));

    }

}

4. 反射機制的應用實例

在泛型為Integer的ArrayList中存放一個String類型的對象。

package net.xsoftlab.baike;

import java.lang.reflect.Method;

import java.util.ArrayList;

public class TestReflect {

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

        ArrayListInteger list = new ArrayListInteger();

        Method method = list.getClass().getMethod(“add”, Object.class);

        method.invoke(list, “Java反射機制實例。”);

        System.out.println(list.get(0));

    }

}

通過反射取得並修改數組的信息

package net.xsoftlab.baike;

import java.lang.reflect.Array;

public class TestReflect {

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

        int[] temp = { 1, 2, 3, 4, 5 };

        Class? demo = temp.getClass().getComponentType();

        System.out.println(“數組類型: ” + demo.getName());

        System.out.println(“數組長度  ” + Array.getLength(temp));

        System.out.println(“數組的第一個元素: ” + Array.get(temp, 0));

        Array.set(temp, 0, 100);

        System.out.println(“修改之後數組第一個元素為: ” + Array.get(temp, 0));

    }

}

將反射機制應用於工廠模式

package net.xsoftlab.baike;

interface fruit {

    public abstract void eat();

}

class Apple implements fruit {

    public void eat() {

        System.out.println(“Apple”);

    }

}

class Orange implements fruit {

    public void eat() {

        System.out.println(“Orange”);

    }

}

class Factory {

    public static fruit getInstance(String ClassName) {

        fruit f = null;

        try {

            f = (fruit) Class.forName(ClassName).newInstance();

        } catch (Exception e) {

            e.printStackTrace();

        }

        return f;

    }

}

/**

 * 對於普通的工廠模式當我們在添加一個子類的時候,就需要對應的修改工廠類。 當我們添加很多的子類的時候,會很麻煩。

 * Java 工廠模式可以參考

 * 

 * 

 * 現在我們利用反射機制實現工廠模式,可以在不修改工廠類的情況下添加任意多個子類。

 * 

 * 但是有一點仍然很麻煩,就是需要知道完整的包名和類名,這裡可以使用properties配置文件來完成。

 * 

 * java 讀取 properties 配置文件 的方法可以參考

 * 

 * 

 * @author xsoftlab.net

 */

public class TestReflect {

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

        fruit f = Factory.getInstance(“net.xsoftlab.baike.Apple”);

        if (f != null) {

            f.eat();

        }

    }

}

我有一個微信公眾號,經常會分享一些Java技術相關的乾貨,還有一些學習資源。

如果你喜歡我的分享,可以用微信搜索「Java團長」或者「javatuanzhang」關注。

什麼是反射?什麼Java反射?

java反射是什麼意思呢?下面帶大家了解一下。

JAVA反射是指程序可以訪問、檢測和修改它本身狀態或行為的一種能力。反射是一種強大的工具,能夠創建靈活的代碼,可以使代碼在運行時裝配,無需在組件之間進行源代表鏈接。

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

反射適合用在哪

首先我們先思考一個問題,反射適合使用在哪裡呢?從功能上看,反射似乎無所不能,幾乎所有的類,所有的屬性、方法、構造我們都能使用,但是我們細細思考一下,在實際開發中,並不是所有場景都需要使用反射獲取屬性或者方法進行操作,反而更多的使用實例.xxx方式操作,而當這些操作重複次數較多的時候,我們往往會考慮優化代碼,減少代碼冗餘,提高復用,比如實體構建賦值等操作,這個時候往往是我們最需要復用的地方,所以我們可以大體認為反射主要使用在實體操作過程中。而在一般操作數據的過程中,我們的實體一般都是知道並且依賴於對應的數據類型的,比如:

1.根據類型new的方式創建對象

2.根據類型定義變數,類型可能是基本類型也可能是引用類型、類或者介面

3.將對應類型的對象傳遞給方法

4.根據類型訪問對象的屬性,調用方法等操作

以上這些操作都是數據操作的過程中最常見也是最難復用優化的地方,而如果這裡的操作使用反射則可以實現動態的操作不同的類型的實例,通過調用反射入口類Class,獲取對應的屬性、構造、方法完成對應的操作

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/239495.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-12 12:16
下一篇 2024-12-12 12:16

相關推薦

  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Bean載入過程

    Java Bean載入過程涉及到類載入器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean載入的過程。 一、類載入器 類載入器是Java虛擬機…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Java判斷字元串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字元串中是否存在多個指定字元: 一、字元串遍歷 字元串是Java編程中非常重要的一種數據類型。要判斷字元串中是否存在多個指定字元…

    編程 2025-04-29
  • VSCode為什麼無法運行Java

    解答:VSCode無法運行Java是因為默認情況下,VSCode並沒有集成Java運行環境,需要手動添加Java運行環境或安裝相關插件才能實現Java代碼的編寫、調試和運行。 一、…

    編程 2025-04-29
  • Java任務下發回滾系統的設計與實現

    本文將介紹一個Java任務下發回滾系統的設計與實現。該系統可以用於執行複雜的任務,包括可回滾的任務,及時恢復任務失敗前的狀態。系統使用Java語言進行開發,可以支持多種類型的任務。…

    編程 2025-04-29
  • Java 8 Group By 會影響排序嗎?

    是的,Java 8中的Group By會對排序產生影響。本文將從多個方面探討Group By對排序的影響。 一、Group By的概述 Group By是SQL中的一種常見操作,它…

    編程 2025-04-29

發表回復

登錄後才能評論