Java反射機制能夠擷取的資訊,與應用

來源:互聯網
上載者:User

標籤:get   simple   hand   參數   lang   illegal   loader   anti   添加   

【1】反射機制是在運行狀態中,對於任何一個類,都能夠知道這個類的所有屬性和方法;

【2】對於任意一個對象,都能夠調用它的任意一個屬性和方法;

  像這種動態擷取類的資訊以及動態調用對象的方法的騷操作稱為java語言的反射機制。

 

二、Java反射機制能夠擷取及操作哪些資訊?

【1】擷取類的包名 + 類名

 1 package com.zyy.test.reflect; 2  3 public class TestReflect { 4  5     public static void main(String[] args) throws ClassNotFoundException { 6         Class<?> class1 = TestReflect.class; 7         Class<?> class2 = new TestReflect().getClass(); 8         Class<?> class3 = Class.forName("com.zyy.test.reflect.TestReflect"); 9         10         System.out.println("包名+類名:" + class1.getName());11         System.out.println("類名" + class1.getSimpleName());12         System.out.println("包名+類名:" + class2.getName());13         System.out.println("類名" + class2.getSimpleName());14         System.out.println("包名+類名:" + class3.getName());15         System.out.println("類名" + class3.getSimpleName());16         17         /*18          列印結果如下:19             包名+類名:com.zyy.test.reflect.TestReflect20             類名TestReflect21             包名+類名:com.zyy.test.reflect.TestReflect22             類名TestReflect23             包名+類名:com.zyy.test.reflect.TestReflect24             類名TestReflect25         */26     }27 28 }

 【2】擷取某個類的父類與實現的介面資訊

 1 package com.zyy.test.reflect; 2  3 import java.io.Serializable; 4  5 public class TestReflect implements Serializable{ 6  7     private static final long serialVersionUID = -8047590384784013451L; 8  9     public static void main(String[] args) throws ClassNotFoundException {10         Class<?> clazz = Class.forName("com.zyy.test.reflect.TestReflect");11         //擷取父類資訊12         System.out.println("父類:" + clazz.getSuperclass().getName());13         //擷取實現的所有介面資訊14         Class<?>[] interfaces = clazz.getInterfaces();15         for (int i = 0; i < interfaces.length; i++) {16             System.out.println("介面:" + interfaces[i].getName());17         }18         19         /*列印結果如下:20             父類:java.lang.Object21             介面:java.io.Serializable22          */23     }24 25 }

【3】擷取某個類的構造資訊以及使用構造進行賦值

 1 package com.zyy.test.reflect; 2  3 import java.lang.reflect.Constructor; 4 import java.lang.reflect.InvocationTargetException; 5 import java.math.BigDecimal; 7  8 public class TestReflect { 9     10     public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, 11         IllegalArgumentException, InvocationTargetException {12         13         Class<?> clazz = Class.forName("com.zyy.test.reflect.BookFacaed");14         Constructor<?>[] constructors = clazz.getConstructors();15         16         for (int i = 0; i < constructors.length; i++) {17             System.out.println("構造" + i + constructors[i].getName() + "的參數為:");18             //擷取構造的參數資訊19             Class<?>[] types = constructors[i].getParameterTypes();20             for (int j = 0; j < types.length; j++) {21                 System.out.println(types[j].getName() + " ");22             }23         }24         25         /*列印結果:26              構造0com.zyy.test.reflect.BookFacaed的參數為:27             java.lang.String 28             java.math.BigDecimal 29             構造1com.zyy.test.reflect.BookFacaed的參數為:30             java.lang.String 31             構造2com.zyy.test.reflect.BookFacaed的參數為:32          */33         34         //執行個體化擁有2個參數的構造方法35         BookFacaed bookFacaed = (BookFacaed)constructors[0].newInstance("《資料結構》", new BigDecimal(100));36         System.out.println(bookFacaed);    //調用實體的toString方法列印37         38         //通過反射機制直接執行個體化對象39         BookFacaed bookFacaed2 = (BookFacaed)clazz.newInstance();40         bookFacaed2.setName("《資料結構》");41         bookFacaed2.setPrice(new BigDecimal(100));42         System.out.println(bookFacaed2);43     }44     45 }46 47 class BookFacaed {48     private String name;49     50     private BigDecimal price;51     52     public BookFacaed () {}53     54     public BookFacaed (String name) {55         this.name = name;56     }57 58     public BookFacaed (String name, BigDecimal price) {59         this.name = name;60         this.price = price;61     }62     63     public String getName() {64         return name;65     }66 67     public void setName(String name) {68         this.name = name;69     }70 71     public BigDecimal getPrice() {72         return price;73     }74 75     public void setPrice(BigDecimal price) {76         this.price = price;77     }78     79     @Override80     public String toString() {81         return name + "的價格為:" + price;82     }83 }

【4】擷取某個類的所有屬性資訊

 1 package com.zyy.test.reflect; 2  3 import java.lang.reflect.Field; 4 import java.lang.reflect.Modifier;public class TestReflect { 5      6     public static void main(String[] args) throws ClassNotFoundException { 7         Class<?> clazz = Class.forName("com.zyy.test.reflect.BookFacaed"); 8         Field[] fields = clazz.getDeclaredFields(); 9         for (int i = 0; i < fields.length; i++) {10             //獲得類屬性的修飾符11             String pri = Modifier.toString(fields[i].getModifiers());12             //獲得類屬性的類型13             Class<?> type = fields[i].getType();14             15             System.out.println(pri + " " + type.getSimpleName() + " " + fields[i].getName());16             /*列印結果:17                 private String name18                 private BigDecimal price19              */20         }21         22         /*如果要擷取類的介面或者父類的屬性使用下面的方法擷取*/23         Field[] fields2 = clazz.getFields();24     }25     26 }

【5】擷取某個類的所有方法及其屬性資訊

 1 package com.zyy.test.reflect; 2  3 import java.lang.reflect.Method; 4 import java.lang.reflect.Modifier; 5 import java.math.BigDecimal; 6  7  8 public class TestReflect { 9     10     public static void main(String[] args) throws ClassNotFoundException {11         Class<?> clazz = Class.forName("com.zyy.test.reflect.BookFacaed");12         13         Method[] methods = clazz.getMethods();14         for (int i = 0; i < methods.length; i++) {15             System.out.println("方法" + (i + 1));16             //擷取方法的修飾符17             String pri = Modifier.toString(methods[i].getModifiers());18             //擷取方法的傳回型別19             Class<?> type = methods[i].getReturnType();20             //擷取方法的持有參數21             Class<?>[] params = methods[i].getParameterTypes();22             for (int j = 0; j < params.length; j++) {23                 System.out.println(params[j].getName());24             }25             //擷取方法的拋出異常26             Class<?>[] excTypes = methods[i].getExceptionTypes();27             for (int j = 0; j < excTypes.length; j++) {28                 System.out.println(excTypes[j].getName());29             }30         }31     }32     33 }

 【6】反射機制調用某個類的某個方法

 1 package com.zyy.test.reflect; 2  3 import java.lang.reflect.InvocationTargetException; 4 import java.lang.reflect.Method; 5 import java.math.BigDecimal; 6  7 public class TestReflect { 8      9     public static void main(String[] args) throws NoSuchMethodException, SecurityException, ClassNotFoundException, 10         IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {11         12         Class<?> clazz = Class.forName("com.zyy.test.reflect.BookFacaed");13         //調用BookFacaed的addBook()方法14         Method method = clazz.getMethod("addBook", String.class);15         method.invoke(clazz.newInstance(), "《資料結構》");16     }17     18 }19 20 class BookFacaed {21     private String name;22     23     private BigDecimal price;24     25     public BookFacaed () {}26     27     public BookFacaed (String name) {28         this.name = name;29     }30 31     public BookFacaed (String name, BigDecimal price) {32         this.name = name;33         this.price = price;34     }35     36     public void addBook(String name) {37         System.out.println("添加書:" + name);38     }39     40     public String getName() {41         return name;42     }43 44     public void setName(String name) {45         this.name = name;46     }47 48     public BigDecimal getPrice() {49         return price;50     }51 52     public void setPrice(BigDecimal price) {53         this.price = price;54     }55     56     @Override57     public String toString() {58         return name + "的價格為:" + price;59     }60 }

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

 1 package com.zyy.test.reflect; 2  3 import java.lang.reflect.Field; 4 import java.math.BigDecimal; 5  6 public class TestReflect { 7      8     public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException,  9         SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException {10         11         Class<?> clazz = Class.forName("com.zyy.test.reflect.BookFacaed");12         Object obj = clazz.newInstance();13         //調用BookFacaed的name屬性,並賦值14         Field field = clazz.getDeclaredField("name");15         field.setAccessible(true); //操作屬性修飾符為private則必須用此申明16         field.set(obj, "《資料結構》");17         18         System.out.println(field.get(obj));19     }20     21 }

三、Java反射機制能夠協助我們做什嗎?

【1】打破泛型的約束

 1 package com.zyy.test.reflect; 2  3 import java.lang.reflect.InvocationTargetException; 4 import java.lang.reflect.Method; 5 import java.math.BigDecimal; 6 import java.util.ArrayList; 7 import java.util.List; 8  9 public class TestReflect {10     11     public static void main(String[] args) throws NoSuchMethodException, SecurityException, 12         IllegalAccessException, IllegalArgumentException, InvocationTargetException {13         14         List<Integer> list = new ArrayList<Integer>();15         //設定了以上泛型之後,list集合中是無法插入String或者其他類型的資料的16         //通過泛型我們便可打破這個約束,代碼如下17         Method method = list.getClass().getMethod("add", Object.class);18         method.invoke(list, "看插入了一個String資料");19         20         System.out.println(list.get(0));21     }22     23 }

【2】反射機制實現動態代理

  Spring的一個核心設計思想便是AOP(面向切面編程),那麼AOP是通過動態代理實現的,而動態代理則用到了反射機制;

  用了反射機制的好處在於,一個代理就能處理所有的委託,而不用一個委託類就建立一個代理;

 1 package com.zyy.test.reflect; 2  3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 import java.lang.reflect.Proxy; 6  7  8 public class TestReflect { 9     10     public static void main(String[] args) {11         //建立代理類並綁定委託類12         FruitProxy proxy = new FruitProxy();13         Fruit fruit = (Fruit) proxy.bind(new Apple());14         fruit.eatFruit();15     }16     17 }18 19 interface Fruit {20     public void eatFruit();21 }22 23 //委託類24 class Apple implements Fruit {25     public void eatFruit() {26         System.out.println("eat Apple");27     }28 }29 30 //代理類31 class FruitProxy implements InvocationHandler{32     private Object obj;33     34     //綁定對象35     public Object bind(Object obj) {36         this.obj = obj;37         return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);38     }39     40     @Override41     public Object invoke(Object proxy, Method method, Object[] args)42             throws Throwable {43         System.out.println("這裡添加執行內容,<aop:before/>標籤熟悉吧,作用一樣");44         Method result = (Method) method.invoke(obj, args);45         System.out.println("這裡添加執行內容,<aop:after/>標籤熟悉吧,作用一樣");46         47         return result;48     }49     50 }

【3】反射機制應用於原廠模式

對於普通的工廠,新增一個子類的時候,工廠就需要進行調整,而加入反射機制後,工廠則不需要關心你有多少個子類;

 1 package com.zyy.test.reflect; 2  3 public class TestReflect { 4      5     public static void main(String[] args) throws InstantiationException,  6         IllegalAccessException, ClassNotFoundException { 7          8         Fruit fruit = (Fruit) Factory.getInstance("com.zyy.test.reflect.Orange"); 9         fruit.eatFruit();10     }11     12 }13 14 interface Fruit {15     public void eatFruit();16 }17 18 class Apple implements Fruit {19     public void eatFruit() {20         System.out.println("eat Apple");21     }22 }23 24 class Orange implements Fruit {25     public void eatFruit() {26         System.out.println("eat Orange");27     }28 }29 30 class Factory {31     public static Object getInstance (String className) throws InstantiationException, 32         IllegalAccessException, ClassNotFoundException {33         34         Object obj = Class.forName(className).newInstance();35         return obj;36     }37     38 }

Java反射機制能夠擷取的資訊,與應用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.