成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java反射

張紅新 / 2386人閱讀

摘要:中的反射反射能夠分析類所擁有的能力的程序稱為反射。獲取類的名稱獲取類的修飾符獲取類所在的包獲取父類的屬性獲取類的構(gòu)造器等等獲得的構(gòu)造器的使用獲取構(gòu)造器有兩種方法。

Java中的反射

反射:能夠分析類所擁有的能力的程序稱為反射。

反射的作用

當(dāng)我們在使用一個(gè)已有的類的時(shí)候,在主代碼的main()方法中使用別的已有的類的時(shí)候,如果被使用的類發(fā)生了改變,那么導(dǎo)致我們的main()方法中也要修改大量的代碼,以適應(yīng)被使用的類的修改。這個(gè)時(shí)候,如果在main()方法使用了反射(reflect),那么就可以通過被使用的類的名字來獲取這個(gè)被使用的類的所有情況(方法、Field等),這樣就不必修改我們的主程序了。只需在被使用類的配置文件中寫上被使用類的名字,在mian()方法中通過讀取這個(gè)配置文件獲得這個(gè)被使用類的名字即可通過反射的方法使用這個(gè)類。即使修改了要使用的類的名字或者實(shí)現(xiàn),所有的修改也只體現(xiàn)在這個(gè)類的配置文件中,將需要修改的地方減至最少,提升了類的可擴(kuò)展性。
反射作用使用示例:
被使用類與使用類:

import java.io.*;
    interface eatable
    {
        public void eat();
    }
    class person implements eatable
    {   
        public void eat()
        {
            System.out.println("person EAT");
        }
    }

    class animal implements eatable
    {   
        public void eat()
        {
            System.out.println("animal EAT");
        }
    }

    public class ClassTest
    {
        public static void main(String[] args)throws Exception
        {
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("file.txt")) ));
            Class className = Class.forName(br.readLine());

            //使用了anima類
            eatable ea= (eatable)className.newInstance(); 
            ea.eat();
        }
    }

被使用類的配置文件:file.txt

animal

各種框架里面大量使用了反射,但是只對(duì)用戶暴露了類名與該類的配置文件,防止被修改。

Java類的class屬性

程序運(yùn)行的時(shí)候,每一個(gè)類(如Person類)在加載的時(shí)候,JVM都會(huì)為這個(gè)類創(chuàng)建一個(gè)static的class成員屬性,這個(gè)class屬性里面記載的都是這個(gè)程序里面所有Person類對(duì)象的信息。
同時(shí)我們可以通過Person類的class屬性獲得這個(gè)Person類的所有情況,如:Person類里面的所有方法對(duì)象,Person類里面的所有屬性,Person類里面的所有構(gòu)造方法對(duì)象。
這個(gè)class屬性的類型就是Class.

獲取類的Class對(duì)象。
Java中的所有類型包括基本類型(int, long, float等等),即使是數(shù)組都有與之關(guān)聯(lián)的Class類的對(duì)象。

如果你在編譯期知道一個(gè)類的名字的話,那么你可以使用如下的方式獲取一個(gè)類的Class對(duì)象:

Class myObjectClass = MyObject.class;

如果你在編譯期不知道類的名字,但是你可以在運(yùn)行期獲得到類名的字符串,那么你則可以這么做來獲取Class對(duì)象:

String className = ... ;//在運(yùn)行期獲取的類名字符串
Class class = Class.forName(className);

在使用Class.forName()方法時(shí),你必須提供一個(gè)類的全名,這個(gè)全名包括類所在的包的名字。例如MyObject類位于com.jenkov.myapp包,那么他的全名就是com.jenkov.myapp.MyObject。

類的class屬性的作用

用于動(dòng)態(tài)獲取類中的成員
1. 可以獲取這個(gè)類的所有方法對(duì)象(注意:Java中一切都是對(duì)象,包括方法,一個(gè)類中的成員,即使連方法也是對(duì)象。) 可以通過這個(gè)方法對(duì)象來使這個(gè)方法被執(zhí)行,將一個(gè)類對(duì)象作為方法對(duì)象的參數(shù)傳入即可。
2. 也可以獲取這個(gè)類的所有成員。
3. 獲取類的名稱
4. 獲取類的修飾符
5. 獲取類所在的包
6. 獲取父類的class屬性
7. 獲取類的構(gòu)造器
等等

獲得的構(gòu)造器的使用

獲取構(gòu)造器有兩種方法。

獲取構(gòu)造器的參數(shù)

使用構(gòu)造器來創(chuàng)建類對(duì)象

訪問類的私有變量即私有方法

訪問私有變量

要想獲取私有變量你可以調(diào)用Class.getDeclaredField(String name)方法或者Class.getDeclaredFields()方法。Class.getField(String name)和Class.getFields()只會(huì)返回公有的變量,無法獲取私有變量。下面例子定義了一個(gè)包含私有變量的類,在它下面是如何通過反射獲取私有變量的例子:

public class PrivateObject {
  private String privateString = null;
  public PrivateObject(String privateString) {
  this.privateString = privateString;
  }
}
PrivateObject privateObject = new PrivateObject("The Private Value");
Field privateStringField = PrivateObject.class.
getDeclaredField("privateString");
privateStringField.setAccessible(true);
String fieldValue = (String) privateStringField.get(privateObject);
System.out.println("fieldValue = " + fieldValue);

這個(gè)例子會(huì)輸出”fieldValue = The Private Value”,The Private Value是PrivateObject實(shí)例的privateString私有變量的值,注意調(diào)用 PrivateObject.class.getDeclaredField(“privateString”)方法會(huì)返回一個(gè)私有變量,這個(gè)方法返回的變量是定義在PrivateObject類中的而不是在它的父類中定義的變量。 注意privateStringField.setAccessible(true)這行代碼,通過調(diào)用setAccessible()方法會(huì)關(guān)閉指定類Field實(shí)例的反射訪問檢查,這行代碼執(zhí)行之后不論是私有的、受保護(hù)的以及包訪問的作用域,你都可以在任何地方訪問,即使你不在他的訪問權(quán)限作用域之內(nèi)。但是你如果你用一般代碼來訪問這些不在你權(quán)限作用域之內(nèi)的代碼依然是不可以的,在編譯的時(shí)候就會(huì)報(bào)錯(cuò)。

訪問私有方法

訪問一個(gè)私有方法你需要調(diào)用 Class.getDeclaredMethod(String name, Class[] parameterTypes)或者Class.getDeclaredMethods() 方法。 Class.getMethod(String name, Class[] parameterTypes)和Class.getMethods()方法,只會(huì)返回公有的方法,無法獲取私有方法。下面例子定義了一個(gè)包含私有方法的類,在它下面是如何通過反射獲取私有方法的例子:

public class PrivateObject {
  private String privateString = null;
  public PrivateObject(String privateString) {
this.privateString = privateString;
  }
  private String getPrivateString(){
return this.privateString;
  }
}
PrivateObject privateObject = new PrivateObject("The Private Value");
Method privateStringMethod = PrivateObject.class.
getDeclaredMethod("getPrivateString", null);
privateStringMethod.setAccessible(true);
String returnValue = (String)
privateStringMethod.invoke(privateObject, null);
System.out.println("returnValue = " + returnValue);

這個(gè)例子會(huì)輸出”returnValue = The Private Value”,The Private Value是PrivateObject實(shí)例的getPrivateString()方法的返回值。
PrivateObject.class.getDeclaredMethod(“privateString”)方法會(huì)返回一個(gè)私有方法,這個(gè)方法是定義在PrivateObject類中的而不是在它的父類中定義的。
同樣的,注意Method.setAcessible(true)這行代碼,通過調(diào)用setAccessible()方法會(huì)關(guān)閉指定類的Method實(shí)例的反射訪問檢查,這行代碼執(zhí)行之后不論是私有的、受保護(hù)的以及包訪問的作用域,你都可以在任何地方訪問,即使你不在他的訪問權(quán)限作用域之內(nèi)。但是你如果你用一般代碼來訪問這些不在你權(quán)限作用域之內(nèi)的代碼依然是不可以的,在編譯的時(shí)候就會(huì)報(bào)錯(cuò)。

#Java中的注解

例如:在重寫一個(gè)方法的時(shí)候,在方法上面加上@Override,在編譯階段就保證編譯成功。這就是注解(Anotation)的作用,這是和注釋不一樣的。
Anotation是一個(gè)接口,Override之類的都是它的實(shí)現(xiàn)類。
獲取注解對(duì)象只有一種方法:反射。

反射與數(shù)組

使用反射技術(shù)創(chuàng)建數(shù)組

int[] intArray = (int[]) Array.newInstance(int.class, 3);

這個(gè)例子創(chuàng)建一個(gè)int類型的數(shù)組。Array.newInstance()方法的第一個(gè)參數(shù)表示了我們要?jiǎng)?chuàng)建一個(gè)什么類型的數(shù)組。第二個(gè)參數(shù)表示了這個(gè)數(shù)組的空間是多大。

使用反射技術(shù)訪問數(shù)組內(nèi)的內(nèi)容
具體可以使用Array.get(…)和Array.set(…)方法來訪問數(shù)組內(nèi)的內(nèi)容。下面是一個(gè)例子:

int[] intArray = (int[]) Array.newInstance(int.class, 3);
Array.set(intArray, 0, 123);
Array.set(intArray, 1, 456);
Array.set(intArray, 2, 789);
System.out.println("intArray[0] = " + Array.get(intArray, 0));
System.out.println("intArray[1] = " + Array.get(intArray, 1));
System.out.println("intArray[2] = " + Array.get(intArray, 2));

獲取數(shù)組對(duì)象的class屬性
如果不通過反射的話你可以這樣來獲取數(shù)組的Class對(duì)象:
>
Class stringArrayClass = String[].class;

如果使用Class.forName()方法來獲取數(shù)組的Class對(duì)象則不是那么簡單。比如你可以像這樣來獲得一個(gè)原生數(shù)據(jù)類型(primitive)int數(shù)組的Class對(duì)象:
>
Class intArray = Class.forName("[I");

在JVM中字母I代表int類型,左邊的‘[’代表我想要的是一個(gè)int類型的數(shù)組,這個(gè)規(guī)則同樣適用于其他的原生數(shù)據(jù)類型。
對(duì)于普通對(duì)象類型的數(shù)組有一點(diǎn)細(xì)微的不同:

Class stringArrayClass = Class.forName("[Ljava.lang.String;");

注意‘[L’的右邊是類名,類名的右邊是一個(gè)‘;’符號(hào)。這個(gè)的含義是一個(gè)指定類型的數(shù)組。

獲取普通原生數(shù)據(jù)類型的class屬性
需要注意的是,你不能通過Class.forName()方法獲取一個(gè)原生數(shù)據(jù)類型的Class對(duì)象。下面這兩個(gè)例子都會(huì)報(bào)ClassNotFoundException:

Class intClass1 = Class.forName("I");
Class intClass2 = Class.forName("int");
通常會(huì)用下面這個(gè)方法來獲取普通對(duì)象以及原生對(duì)象的Class對(duì)象:

public Class getClass(String className){
if("int" .equals(className)) return int.class;
if("long".equals(className)) return long.class;
...
return Class.forName(className);
}

一旦你獲取了類型的Class對(duì)象,你就有辦法輕松的獲取到它的數(shù)組的Class對(duì)象,你可以通過指定的類型創(chuàng)建一個(gè)空的數(shù)組,然后通過這個(gè)空的數(shù)組來獲取數(shù)組的Class對(duì)象。這樣做有點(diǎn)討巧,不過很有效。如下例:

Class theClass = getClass(theClassName);
Class stringArrayClass = Array.newInstance(theClass, 0).getClass();

這是一個(gè)特別的方式來獲取指定類型的指定數(shù)組的Class對(duì)象。無需使用類名或其他方式來獲取這個(gè)Class對(duì)象。
為了確保Class對(duì)象是不是代表一個(gè)數(shù)組,你可以使用Class.isArray()方法來進(jìn)行校驗(yàn):

Class stringArrayClass = Array.newInstance(String.class, 0).getClass();
System.out.println("is array: " + stringArrayClass.isArray());

獲取數(shù)組的成員的class屬性
一旦你獲取了一個(gè)數(shù)組的class屬性,你就可以通過class.getComponentType()方法獲取這個(gè)數(shù)組的成員類型。
成員類型就是數(shù)組存儲(chǔ)的數(shù)據(jù)類型。例如,數(shù)組int[]的成員類型就是一個(gè)Class對(duì)象int.class。String[]的成員類型就是java.lang.String類的Class對(duì)象。
下面是一個(gè)訪問數(shù)組成員的class屬性的例子:

String[] strings = new String[3];
Class stringArrayClass = strings.getClass();
Class stringArrayComponentType = stringArrayClass.getComponentType();
System.out.println(stringArrayComponentType);

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/64187.html

相關(guān)文章

  • Java筆記-反射機(jī)制(一)

    摘要:反射機(jī)制一結(jié)合官方通過編寫的反射教程,復(fù)習(xí)一下反射的知識(shí)。反射的概念反射是一種在運(yùn)行時(shí)獲取以及修改應(yīng)用行為的一種工具。因?yàn)榉瓷湫枰獎(jiǎng)討B(tài)的解析類的信息,相比于非反射使用的方式要慢。反射需要獲取一定的運(yùn)行時(shí)權(quán)限,在特定的安全環(huán)境下不一定存在。 Java反射機(jī)制(一) 結(jié)合Oracle官方通過JDK8編寫的反射教程,復(fù)習(xí)一下反射的知識(shí)。結(jié)尾篇補(bǔ)一個(gè)小例子。 主要內(nèi)容 這次博客的主要內(nèi)容就是簡...

    AWang 評(píng)論0 收藏0
  • Java 反射教程

    摘要:反射非常強(qiáng)大和有用。另外,反射可以用在映射結(jié)果集的列名到對(duì)象的方法。本教程將深入介紹反射。本教程還將清除一些關(guān)于范型信息在運(yùn)行時(shí)可用性的認(rèn)知混淆。類對(duì)象使用反射時(shí),起點(diǎn)通常是需要使用反射檢視的類的對(duì)象。 Java反射可以在運(yùn)行時(shí)檢視類、接口、屬性和方法,而無需在編譯時(shí)知道類名、方法名等等。它也同樣使用反射支持實(shí)例化新的對(duì)象、調(diào)用方法和get/set屬性值。 Java反射非常強(qiáng)大和有用...

    klivitamJ 評(píng)論0 收藏0
  • Java反射詳細(xì)介紹

    摘要:通過反射獲取帶參無返回值成員方法并使用設(shè)置安全檢查,訪問私有構(gòu)造函數(shù)必須創(chuàng)建實(shí)例這種不行,注意和方法需要傳遞參數(shù)測試復(fù)制這個(gè)功能獲取私有方法,同樣注意和的區(qū)別賦予訪問權(quán)限調(diào)用方法。 反射 目錄介紹 1.反射概述 1.1 反射概述 1.2 獲取class文件對(duì)象的三種方式 1.3 反射常用的方法介紹 1.4 反射的定義 1.5 反射的組成 1.6 反射的作用有哪些 2.反射的...

    ingood 評(píng)論0 收藏0
  • Java反射學(xué)習(xí)小記

    摘要:反射使用類對(duì)象提供的基本元數(shù)據(jù),能從類對(duì)象中找出方法或字段的名稱,然后獲取表示方法或字段的對(duì)象。常見的反射手段有反射和反射。以之前的反射為例其中指定了方法的返回類型,其實(shí)不止如此。 Java反射機(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)代理 很多框架...

    frank_fun 評(píng)論0 收藏0
  • Reflection:Java反射機(jī)制的應(yīng)用場景

    近期在維護(hù)公司項(xiàng)目的時(shí)候遇到一個(gè)問題,因?yàn)閷?shí)體類中的 set 方法涉及到了業(yè)務(wù)邏輯,因此在給對(duì)象賦值的過程中不能夠使用 set 方法,為了實(shí)現(xiàn)功能,所以采用了反射的機(jī)制給對(duì)象屬性賦值,借此機(jī)會(huì)也了解了反射的一些具體用法和使用場景,分以下兩點(diǎn)對(duì)反射進(jìn)行分析: 反射的優(yōu)勢和劣勢 反射的應(yīng)用場景 反射的優(yōu)勢和劣勢 ??個(gè)人理解,反射機(jī)制實(shí)際上就是上帝模式,如果說方法的調(diào)用是 Java 正確的打開方式...

    浠ラ箍 評(píng)論0 收藏0
  • 樂字節(jié)Java反射之一:反射概念與獲取反射源頭class

    摘要:一反射機(jī)制概念程序運(yùn)行時(shí),允許改變程序結(jié)構(gòu)或變量類型,這種語言稱為動(dòng)態(tài)語言,如,是動(dòng)態(tài)語言顯然,,不是動(dòng)態(tài)語言,但是有著一個(gè)非常突出的動(dòng)態(tài)相關(guān)機(jī)制。相關(guān)的為二獲取源頭重點(diǎn)打開權(quán)限所有類的對(duì)象其實(shí)都是的實(shí)例。 一、Java反射機(jī)制概念 程序運(yùn)行時(shí),允許改變程序結(jié)構(gòu)或變量類型,這種語言稱為動(dòng)態(tài)語言,如Python, Ruby是動(dòng)態(tài)語言;顯然C++,Java,C#不是動(dòng)態(tài)語言,但是JAVA有...

    caikeal 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<