首頁  >  文章  >  Java  >  Java反射機制的知識點有哪些

Java反射機制的知識點有哪些

王林
王林轉載
2023-05-21 12:34:20994瀏覽

類別的宣告週期

java原始碼----->javac-------------->java字節碼檔----- --------->java----------------->類別物件(所在記憶體空間:元空間,本地記憶體)------ ------------------new--------->實例化物件----------------- -gc------------->卸載物件

Java反射機制的知識點有哪些

不同階段都可以取得類別物件

  • #物件.getClass() (記憶體階段)

  • Test.class (元空間)

  • class.forName(「類別全名:包名類別名稱”) :(硬碟)都沒有進入記憶體空間就可以拿到物件

舉例來說,當我們使用jdbc操作資料庫時,在這個類別進入在記憶體之前,我們可以使用該類別的完整名稱-包名類別名,呼叫該類別並使用

Java反射機制的知識點有哪些

取得Class類別物件的方式的場景

  • Class.forName(“類別全名”) :多用於設定文件,將類別名稱定義在設定檔中,讀取設定文件,載入類別

  • 類別名稱.class : 多重用於參數的傳遞

  • 物件名稱.getClass():多用於物件取得類別物件

總結:同一個類別載入器載入的檔案在一次程式運行過程中,只會被載入一次,無論使用哪種方式取得的類別物件都是同一個

程式碼範例:

package com.reflect;
public class TestReflectPerson {
    public static void main(String[] args) throws ClassNotFoundException {
        //1.class.forName()
        Class class1=Class.forName("com.reflect.Person");
        System.out.println(class1);
        //2.类名.class
        Class class2=Person.class;
        System.out.println(class2);
        //2.对象名.getClass()
        Class class3=new Person().getClass();
        System.out.println(class3);
        System.out.println(class1==class2);  //true
        System.out.println(class2==class3);  //true
    }
}

class類別物件的功能

取得成員變數: 取所有:類別物件.getDeclaredFields() ,取得一個:類別物件.getDeclaredField()

  • #設定值set (Object obj,Object value)

  • 取得值get(Object obj)

取得任意權限修飾的成員變數取得設定值,需要使用setAccessible(true)-----暴力反射

成員方法: 類別物件.getDeclaredMethods()

執行方法invoke(Object object ,Object… agrs)(參數個數任意,可有可無)

取得方法名稱getName()

建構方法: 類別物件.getDeclaredConstructors()

雖然必須具備無參考構造方法,但使用newInstance( ) 方法可以省略取得建構方法並取得物件的步驟

此方法需要實際情況建構方法賦實參

//获得构造方法对象,
        Constructor cons1 = pcla.getDeclaredConstructor(String.class, int.class);
        Person p2 = (Person)cons1.newInstance("李四",19);
        System.out.println("p2:"+p2.getName());

newInstance()如果是建立無參構造方法去建立對象,可以使用類別物件來建立對象,跳過獲得建構方法物件

取得

#取得類別的名稱:getName() 列印出全名:類別名稱包名

#只想要列印單獨類別名稱:getSimpleName()

取得類別的成員變數名稱

Java反射機制的知識點有哪些

屬性檔案:內容以等號連接形狀如k=v,

Java反射機制的知識點有哪些

程式碼範例:

package com.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class TestReflectPerson {
    public static void main(String[] args) throws Exception {
       /* //1.class.forName()
        Class class1=Class.forName("com.reflect.Person");
        System.out.println(class1);
        //2.类名.class
        Class class2=Person.class;
        System.out.println(class2);
        //2.类名.getClass()
        Class class3=new Person().getClass();
        System.out.println(class3);
        System.out.println(class1==class2);
        System.out.println(class2==class3);*/
        //获取对象
        Class tclass=Class.forName("com.reflect.Person");
        //通过类对象获取成员变量们
        Field[] fields = tclass.getDeclaredFields();
        System.out.println("获取Person对象的所有属性对象");
        for (Field field:fields){
           System.out.println(field);
       }
        //指定获取Person对象的属性对象
        System.out.println("指定获取Person对象的属性对象");
        Field age=tclass.getDeclaredField("age");
        System.out.println("age:"+age);
        //通过类对象获取所有的构造方法
        Constructor[] constructors = tclass.getDeclaredConstructors();
        System.out.println("获取Person的所有构造方法对象");
        for (Constructor constructor:constructors){
            System.out.println(constructor);
        }
        //通过类对象获取无参的构造方法
        Constructor constructor = tclass.getDeclaredConstructor();
        System.out.println("constructor:"+constructor);
        //通过类对象获取有参的构造方法
        Constructor constructor1 = tclass.getDeclaredConstructor(String.class,int.class);
        System.out.println("constructor1:"+constructor1);
        //通过类对象获取所有的成员方法
        Method[] methods = tclass.getDeclaredMethods();
        for (Method method:methods){
            System.out.println("method:"+method);
        }
        //通过类对象获取getAge成员方法
        Method getAge = tclass.getDeclaredMethod("getAge");
        System.out.println("getAge:"+getAge);
        //通过类对象获取getAge成员方法
        Method setAge = tclass.getDeclaredMethod("setAge", int.class);
        System.out.println("setAge:"+setAge);
    }
}

取得成員變數程式碼範例:

package com.reflect;
import java.lang.reflect.Field;
public class TestField {
    public static void main(String[] args) throws Exception {
        Class pcla=Person.class;
        /*//获取公共访问权限的成员变量
        Field[] fields = pcla.getFields();
        for (Field field:fields){
            System.out.println("getFild:"+field);
        }
        System.out.println();
        //获取所有访问权限的成员变量
        Field[] fielddes = pcla.getDeclaredFields();
        for (Field field:fielddes){
            System.out.println("field:"+field);
        }*/
        Field name = pcla.getDeclaredField("name");
        System.out.println(name);
        Person person=new Person();
        //暴力反射:获取任意访问权限修饰符的安全检查
        name.setAccessible(true);
        //获取公共成员变量的值
        Object value = name.get(person);
        System.out.println(value);
        //获取任意访问权限的成员变量的值
        Object value2 = name.get(person);
        System.out.println("value2:"+value2);
        //设置任意访问权限的成员变量的值
        name.set(person,"张三");
        Object value3=name.get(person);
        System.out.println("name:"+value3);
    }
}

如何取得私有變數的值

//暴力反射:获取任意访问权限修饰符的安全检查
name.setAccessible(true);

根據有無主方法判斷行程和執行緒

程式:含有自己的主方法,可以依托自己的主方法啟動,叫做行程

執行緒:沒有自己的主方法,需要依賴其他工具來運行

例如:servlet就需要藉助tomcate來運行,tomcate有自己的一個主方法

反射出現的背景(記住)

範例:在當servlet透過使用工具tomcate來運作時,tomacate執行專案時存取不到類別的資源,產生了反射

tomcate為何拿不到new的物件

詳解:tomcate不可能透過new的方式來調用,因為tomacate是先產生寫好的,類別是後來寫的,所以tomcate不知道new的物件的是什麼,可以透過套件掃描的方式來取得檔案路徑,但是這樣也無法使用new的方式,由此產生了反射。

ate有自己的一個主方法

反射出現的背景

範例:在servlet透過借助工具tomcate來運行時,tomacate運行專案時訪問不到類別的資源,由此產生了反射

tomcate為什麼拿不到new的物件?

詳解:tomcate不可能用new的方式來調用,因為tomacate是先產生寫好的,類別是後來寫的,所以tomcate不知道new的物件的是什麼,可以透過套件掃描的方式來取得檔案路徑,但是這樣也無法使用new的方式,因此產生了反射。

tomcate想調用doGet,doPost的方法時,因為這兩個方法不是靜態的,必須透過new對象才能調用,但是tomcate又不能創建對象,所以由此產生反射來獲取文件

以上是Java反射機制的知識點有哪些的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除