JAVA之Class類與反射總結__JAVA

來源:互聯網
上載者:User

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

  1.取得Class類的對象的三種方法

      取得Class對象:public final Class<?> getClass(),反射之中的所有泛型都定義為。,傳回值都是Object。 通過Object類的getClass()方法取得

<span style="color:#000000;">class Person{} public class TestDemo{ public static void main(String[] args) throws Exception{Person per = new Person();Class<?> cls = per.getClass();System.out.println(cls.getName());}}</span>

  使用“類.Class”取得

<span style="font-size:12px;"> class Person{} public class TestDemo{ public static void main(String[] args) throws Exception{Class<?> cls = Person.class;System.out.println(cls.getName());}}</span>

  使用Class類內部定義的一個static方法

    取得Class類對象:public static Class<?>forName(String className) throws ClassNotFoundException

class Person{} public class TestDemo{ public static void main(String[] args) throws Exception{Class<?> cls = Class.forName("Person");//取得Class對象System.out.println(cls.getName());}}

2.通過反射執行個體化對象

    通過反射執行個體化對象:public T newInstance () throws InstantiationException,IllegalAccessException

class Person{ public String toString(){ return "Person Class Instance."; } } public class TestDemo{ public static void main(String[] args) throws Exception{Class<?> cls = Class.forName("Person");//取得Class對象Object obj = cls.newInstance();  //執行個體化對象,和使用關鍵字new一樣Person per = (Person) obj ; //向下轉型System.out.println(per);} }


範例:原廠模式

<span style="font-size:12px;">interface Fruit{public void eat();}class Apple implements Fruit{public void eat(){System.out.println("吃蘋果。");}}class Factory{public static Fruit getInstance(String className){if("apple".equals(className)){return new Apple();}return null;}}public class FactoryDemo {public static void main(String[] args) {Fruit f = Factory.getInstance("apple");f.eat();}}</span>


    在這個工廠設計模式之中有一個最大的問題:如果現在介面的子類增加了,那麼工廠類肯定需要修改,這是它所面臨的最大問題,而這個最大問題造成的關鍵性病因是new,那麼如果說現在不使用關鍵字new了,變為了反射機制呢。

 

interface Fruit{public void eat();}class Apple implements Fruit{public void eat(){System.out.println("吃蘋果。");}}class Orange implements Fruit{public void eat(){System.out.println("吃橘子。");}}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 ;}}public class FactoryDemo {public static void main(String[] args) {Fruit f = Factory.getInstance("Orange");f.eat();}}

3.調用構造方法

編號

方法名稱 傳回值類型 說明

1

getConstructors()

Constructor數組

擷取所有許可權為public的構造方法

2

getConstructor(Class<?>…parameterTypes)

Constructor對象

擷取許可權為public的指定構造方法

3

getDeclaredConstructors()

Constructor數組

獲得所有構造方法,按聲明順序返回

4

getDeclaredConstructor(Class<?>…parameterTypes)

Constructor對象

獲得指定的構造方法

<span style="font-size:12px;">import java.lang.reflect.Constructor; class Person{ public Person(){} public Person(String name){} public Person(String name , int age){} } public class TestDemo{ public static void main(String[] args) throws Exception{Class<?> cls = Class.forName("Person");//取得Class對象Constructor<?> cons []  = cls.getConstructors();  //取得全部構造for(int x = 0 ; x < cons.length ; x ++){System.out.println(cons[x]);}} }</span>


範例:調用有參數的構造方法

import java.lang.reflect.Constructor; class Person{ private String name; private int age ; public Person(String name , int age){ this.name = name ; this.age = age ; } public String toString(){ return "Person [name="+name+",age="+age+"]" ; } } public class TestDemo{ public static void main(String[] args) throws Exception{Class<?> cls = Class.forName("Person");//取得Class對象//取得指定參數類型的構造方法Constructor<?> cons = cls.getConstructor(String.class,int.class);Object obj = cons.newInstance("張三",20);//為構造方法傳遞參數System.out.println(obj); } }

4.調用普通方法

編號

  方法名稱   傳回值類型   說明

1

getMethods()

Method數組

擷取所有許可權為public的方法

2

getMethod(String name,Class<?>…parameterTypes)

Method對象

擷取許可權為public的指定方法

3

getDeclaredMethods()

Method數組

獲得所有方法,按聲明順序返回

4

getDeclaredMethod(String name,Class<?>…parameterTypes)

Method對象

獲得指定的方法

 

import java.lang.reflect.Constructor;import java.lang.reflect.Method; class Person{private String name;public String getName() {return name;}public void setName(String name) {this.name = name;} } public class TestDemo{ public static void main(String[] args) throws Exception{Class<?> cls = Class.forName("Person");//取得Class對象Method met [] = cls.getMethods();for(int x = 0 ; x < met.length ; x ++){System.out.println(met[x]);} } }


    取得了Method類對象之後有一個最大的功能,就是可以利用反射調用類中的方法。調用方法:

public Object invoke(Object obj,Object…args) throws IllegalAccessException,IllegalArgumentException,InyocationTargetException

 

import java.lang.reflect.Method; class Person{private String name;public String getName() {return name;}public void setName(String name) {this.name = name;} } public class TestDemo{ public static void main(String[] args) throws Exception{Class<?> cls = Class.forName("Person");//取得Class對象Object obj = cls.newInstance();String attribute = "name"; //要調用類之中的屬性Method setMet = cls.getMethod("set"+initcap(attribute),String.class);//setName()Method getMet = cls.getMethod("get"+initcap(attribute));//getName()setMet.invoke(obj, "張三");//等價於:Person對象.setName("張三");System.out.println(getMet.invoke(obj));           //等價於:Person對象.getName() } public static String initcap(String str){ return str.substring(0,1).toUpperCase().concat(str.substring(1)); } }

5.調用成員

編號

方法名稱   傳回值類型 說明

1

getFields()

Field數組

擷取所有許可權為public的成員變數

2

getField(String name)

Field對象

擷取許可權為public的指定成員變數

3

getDeclaredFields()

Field數組

獲得所有成員變數,按聲明順序返回

4

getDeclaredField(String name)

Field對象

獲得指定的構造方法

<span style="font-size:12px;">import java.lang.reflect.Field;import java.lang.reflect.Method; class Person{private String name; } public class TestDemo{ public static void main(String[] args) throws Exception{Class<?> cls = Class.forName("Person");//取得Class對象Field field [] = cls.getDeclaredFields();for(int x = 0 ; x < field.length ; x++) {System.out.println(field[x]);}} }</span>


在Field類之中提供了兩個方法: 設定屬性內容(類似於:對象.屬性 = 內容):
public void set(Object obj,Object value) throws IllegalArgumentExcepiton,IllegalAccessException ; 取得屬性內容(類似於:對象.屬性):
public Object get(Object obj) throws IllegalArgumentException,IllegalAccessException

從類的開發要求而言,一直都強調之中類之中的屬性必須封裝,所以現在調用之前要想盡一切方法解除封裝。 解除封裝:public void setAccessible(boolean flag)throws SecurityException;

<span style="font-size:12px;">import java.lang.reflect.Field; class Person{private String name; } public class TestDemo{ public static void main(String[] args) throws Exception{Class<?> cls = Class.forName("Person");//取得Class對象Object obj = cls.newInstance();  //對象執行個體化屬性才會分配空間Field nameField  = cls.getDeclaredField("name"); //找到name屬性nameField.setAccessible(true);nameField.set(obj,"張三");//Person對象.name = "張三"System.out.println(nameField.get(obj)); } }</span>

6.其他可以通過反射訪問的主要描述資訊

組成部分

存取方法 傳回值類型 說明

包路徑

getPackage()

Package對象

獲得該類的存放路徑

類名稱

getName()

String對象

獲得該類的名稱

繼承類

getSuperclass()

Class對象

獲得該類的繼承的類

實現介面

getInterfaces()

Class數組

獲得該類實現的所有介面

內部類

getClasses()

getDeclaredClasses()

Class數組

獲得所有許可權為public的內部類

獲得所有內部類

內部類的聲明類

getDeclaringClass()

Class對象

如果該類為內部類,則返回它的成員類,否則返回null

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.