程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java中的反射

Java中的反射

編輯:關於JAVA

Java中的反射。本站提示廣大學習愛好者:(Java中的反射)文章只能為提供參考,不一定能成為您想要的結果。以下是Java中的反射正文


Java反射API

Java反射指的是在運轉形態時,可以獲取類的屬性和辦法或許修正類運轉時行為的進程。

java.lang.Class類提供了很多辦法用於獲取元數據、反省和改動類運轉時的行為。

Java的反射次要觸及java.lang和java.lang.reflect包下的類。

反射使用場景舉例
  1. IDE, 如Eclipse、MyEclipse、NetBeans等;
  2. 調試器;
  3. 測試工具等;
  4. 各大框架、spring、hibernate等;
java.lang.Class類

java.lang.Class次要提供了以下兩個功用:

  1. 提供辦法用於訪問運轉時期類的元數據;
  2. 提供辦法用於反省和修正類的運轉時行為;
java.lang.Class類常用辦法 MethodDescription 1) public String getName() 前往類名 2) public static Class forName(String className)throws ClassNotFoundException 加載類並前往Class對象 3) public Object newInstance()throws InstantiationException,IllegalAccessException 創立實例對象 4) public boolean isInterface() 判別能否是接口 5) public boolean isArray() 判別能否是數組 6) public boolean isPrimitive() 判別能否是原始數據類型 7) public Class getSuperclass() 前往父類Class援用 8) public Field[] getDeclaredFields()throws SecurityException 前往類的成員屬性字段數組 9) public Method[] getDeclaredMethods()throws SecurityException 前往類的辦法數組 10) public Constructor[] getDeclaredConstructors()throws SecurityException 前往類的結構辦法數組 11) public Method getDeclaredMethod(String name,Class[] parameterTypes)throws NoSuchMethodException,SecurityException 前往類中指定參數類型的辦法 怎樣獲取Class對象

有三種方式,如下:

  1. Class類的forName()辦法,靜態加載,運轉時,開端裝入類, 並做類的靜態初始化
  2. 對象的getClass()辦法,靜態加載(編譯時已加載)
  3. .class語法, 靜態加載(編譯時已加載)

forName()辦法示例

可用於靜態加載,當你知道類的全限定名時,可以運用該方式。留意原始數據類型不適用該辦法;

package tmp;

class Simple
{
}

public class Test
{
    public static void main(String args[]) throws ClassNotFoundException
    {
        Class<?> c = Class.forName("tmp.Simple");
        System.out.println(c.getName());
        System.out.println(c.getSimpleName());
    }
}
tmp.Simple
Simple

getClass()辦法示例:

從實例對象中獲取Class對象

package tmp;

class Simple
{
}

public class Test
{
    void printName(Object obj)
    {

    }

    public static void main(String args[])
    {
        Simple s = new Simple();
        Class<? extends Object> c = s.getClass();
        System.out.println(c.getName());
        System.out.println(c.getSimpleName());
    }
}
tmp.Simple
Simple

.class語法示例

作用於類名上,也可使用於原始數據類型,如下所示:

package tmp;

public class Test
{
    public static void main(String args[])
    {
        Class<Boolean> c = boolean.class;
        System.out.println(c.getName());

        Class<Test> c2 = Test.class;
        System.out.println(c2.getName());
    }
}
boolean
tmp.Test 判別Class對象對應的類型

以下辦法可用於判別Class對象對應的類型:

1) public boolean isInterface(): 能否對應接口 2) public boolean isArray(): 能否對應數組 3) public boolean isPrimitive(): 能否對應原始數據類型

代碼示例:

package tmp;

class Simple
{
}

interface My
{
}

public class Test
{
    public static void main(String args[])
    {
        try
        {
            Class<?> c = Class.forName("tmp.Simple");
            System.out.println(c.isInterface());

            Class<?> c2 = Class.forName("tmp.My");
            System.out.println(c2.isInterface());

        }
        catch (Exception e)
        {
            System.out.println(e);
        }

    }
}
false
true 經過反射創立實例對象

有兩種方式,如下:

  1. 經過Class對象的newInstance()辦法創立,這種方式只能調用無參結構辦法;
  2. 經過Constructor對象的newInstance()辦法創立,這種方式適用於有參結構辦法,並且還可以毀壞單例形式,調用公有結構辦法;

所以,通常來講,第二種方式比第一種運用范圍更廣。

Class對象調用newInstance()辦法示例

package tmp;

class Simple
{
    void message()
    {
        System.out.println("Hello Java");
    }
}

public class Test
{
    public static void main(String args[])
    {
        try
        {
            Class<?> c = Class.forName("tmp.Simple");
            Simple s = (Simple) c.newInstance();
            s.message();
        }
        catch (Exception e)
        {
            System.out.println(e);
        }

    }
}
Hello Java

Constructor對象調用newInstance()辦法示例

留意這裡可以依據傳入參數的類型來失掉指定的結構辦法,還可以改動結構辦法的訪問權限限制。

package tmp;

import java.lang.reflect.Constructor;

class Simple
{
    private String msg;
    void message()
    {
        System.out.println("Hello Java," + msg);
    }
    private Simple(String s){
        this.msg = s;
    }
}

public class Test
{
    public static void main(String args[])
    {
        try
        {
            Class<?> c = Class.forName("tmp.Simple");
            Constructor<?> con = c.getDeclaredConstructor(String.class);
            con.setAccessible(true);
            Simple s = (Simple) con.newInstance("...");
            s.message();
        }
        catch (Exception e)
        {
            System.out.println(e);
        }

    }
}
Hello Java,... 經過反射調用公有辦法

經過反射,我們可以調用其它類的公有辦法,次要觸及java.lang.Class和java.lang.reflect.Method類;

其中次要是用到了Method類的setAccessible辦法和invoke辦法,前者修正訪問權限,後者調用辦法。

經過調用有參公有辦法示例:

package tmp;

import java.lang.reflect.Method;

class A
{
    private void cube(int n)
    {
        System.out.println(n * n * n);
    }
}

class Test
{
    public static void main(String args[]) throws Exception
    {
        Class<A> c = A.class;
        Object obj = c.newInstance();

        Method m = c.getDeclaredMethod("cube", new Class[]{ int.class });
        m.setAccessible(true);
        m.invoke(obj, 4);
    }
}
關於javap工具

運用javap命令可以反匯編java的字節碼文件,展現class文件中的字段屬性、結構辦法、普通辦法信息;

運用闡明:

javap java.lang.Object示例

javap -c Test示例:

寫個復雜的Test類,如下:

package tmp;

class Simple
{

}

public class Test
{
    public static void main(String args[])
    {
        System.out.println("Hello");

    }
}

輸出javap -c Test:

 參考材料

根本屬於翻譯,做了小局部修正

http://www.javatpoint.com/java-reflection

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved