Java 反射機(jī)制
簡介:
Java的反射(reflection)機(jī)制是指在程序的運(yùn)行狀態(tài)中,可以構(gòu)造任意一個(gè)類的對象,可以了解任意一個(gè)對象所屬的類,可以了解任意一個(gè)類的成員變量和方法,可以調(diào)用任意一個(gè)對象的屬性和方法。這種動態(tài)獲取程序信息以及動態(tài)調(diào)用對象的功能稱為Java語言的反射機(jī)制。反射被視為動態(tài)語言的關(guān)鍵。
1、反射:通過對象反射出一個(gè)類
package com.example.java.javakuangstudy.Reflection; /** * 反射練習(xí)-->得到class類的幾種方式 */ public class Text01 { public static void main(String[] args) throws ClassNotFoundException { Person person = new Student(); System.out.println("我這個(gè)人是:" + person.name); //TODO 方式一:通過對象獲取 Class<? extends Person> c1 = person.getClass(); System.out.println(c1.hashCode()); //TODO 方式二: Class<?> c2 = Class.forName("com.example.java.javakuangstudy.Reflection.Student"); System.out.println(c2.hashCode()); //TODO 方式三:通過類名.class獲取 Class<Student> c3 = Student.class; System.out.println(c3.hashCode()); //TODO 方式四:基本內(nèi)置類型的包裝類都有一個(gè)type屬性 Class<Integer> c4 = Integer.TYPE; System.out.println(c4); //TODO 獲取父類類型 Class<?> c5 = c1.getSuperclass(); System.out.println(c5); } } class Person { public String name; public Person(String name) { this.name = name; } public Person() { } @Override public String toString() { return "Person{" + "name='" + name + '\'' + '}'; } } class Student extends Person { public Student() { this.name = "學(xué)生"; } } class Teacher extends Person { public Teacher() { this.name = "老師"; } }
結(jié)果
我這個(gè)人是:學(xué)生
834600351
834600351
834600351
intclass com.example.java.javakuangstudy.Reflection.Person
2、分析類的初始化
package com.example.java.javakuangstudy.Reflection; /** * 測試類什么時(shí)候會初始化 */ public class Text02 { static { System.out.println("Main被加載"); } public static void main(String[] args) throws ClassNotFoundException { //TODO 通過new 主動引用 //Son son = new Son(); //TODO 通過反射也會產(chǎn)生主動引用 //Class.forName("com.example.java.javakuangstudy.Reflection.Son"); //TODO 不會產(chǎn)生類的引用的方法 //TODO 1、子類調(diào)用父類的靜態(tài)方法 //int b = Son.b; //System.out.println(b); // TODO 2、通過數(shù)組 //Son[] arr = new Son[5]; //只打印--- Main被加載 (父類子類都不加載) //TODO 3、調(diào)用常量 System.out.println(Son.M); } } class Father { static int b = 2; static { System.out.println("父類被加載"); } } class Son extends Father { static { System.out.println("子類被加載"); m = 300; } static int m = 100; static final int M = 1; }
3、動態(tài)的創(chuàng)建對象 通過反射
package com.example.java.javakuangstudy.Reflection; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * 動態(tài)的創(chuàng)建對象 通過反射 */ @SuppressWarnings("all") public class Text03 { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { //TODO 獲得class對象 Class c1 = Class.forName("com.example.java.javakuangstudy.Reflection.User"); //TODO 構(gòu)造一個(gè)對象 User user = (User) c1.newInstance(); //本質(zhì)是調(diào)用了類的無參構(gòu)造 System.out.println(user); //TODO 通過構(gòu)造器創(chuàng)建對象 Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class); User user1 = (User) constructor.newInstance("liulianglin", 24, 251314); System.out.println(user1); //TODO 通過反射調(diào)用普通方法 User user2 = (User) c1.newInstance(); //TODO 通過反射獲取一個(gè)方法 Method setName = c1.getDeclaredMethod("setName", String.class); //TODO invoke激活的意思 (對象,"方法的值") setName.invoke(user2, "劉亮林"); System.out.println(user2.getName()); //TODO 通過反射操作方法 System.out.println("----------------------"); User user3 = (User) c1.newInstance(); Field name = c1.getDeclaredField("name"); //TODO 不能直接操作私有屬性,我們需要關(guān)閉程序的安全檢測,將setAccessible(true) 可提高效率 name.setAccessible(true); name.set(user3, "liulianglin"); System.out.println(user3.getName()); } }
4、 練習(xí)反射操作注解
package com.example.java.javakuangstudy.Reflection; import java.lang.annotation.*; import java.lang.reflect.Field; /** * 練習(xí)反射操作注解 */ @SuppressWarnings("all") public class Text04 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException { Class c1 = Class.forName("com.example.java.javakuangstudy.Reflection.Student2"); //TODO 通過反射獲取全部注解 Annotation[] annotations = c1.getAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation); //@com.example.java.javakuangstudy.Reflection.Tablekuang(value=db_student) } //TODO 獲得注解的value值 Tablekuang tablekuang = (Tablekuang) c1.getAnnotation(Tablekuang.class); String value = tablekuang.value(); System.out.println(value); //db_student //TODO 獲得類指定的注解 Field name = c1.getDeclaredField("id"); Fieldkuang annotation = name.getAnnotation(Fieldkuang.class); System.out.println(annotation.columnName()); //db_id System.out.println(annotation.type()); //int System.out.println(annotation.length()); //18 } } @Tablekuang("db_student") class Student2 { @Fieldkuang(columnName = "db_id", type = "int", length = 18) private int id; @Fieldkuang(columnName = "db_age", type = "int", length = 18) private int age; @Fieldkuang(columnName = "db_name", type = "varchar", length = 18) private String name; public Student2() { } public Student2(int id, int age, String name) { this.id = id; this.age = age; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Student2{" + "id=" + id + ", age=" + age + ", name='" + name + '\'' + '}'; } } //TODO 類名的注解 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interface Tablekuang { String value(); } //TODO 屬性的注解 @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @interface Fieldkuang { String columnName(); String type(); int length(); }
到此這篇關(guān)于Java 反射機(jī)制的文章就介紹到這了,更多相關(guān)Java反射內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
idea注入mapper報(bào)錯(cuò)報(bào)紅的幾種解決方案
相信大家在使用idea的時(shí)候一定會遇到這樣的問題,就是在service里注入mapper的時(shí)候,明明代碼沒有問題,也可以運(yùn)行,但是idea它就是給你報(bào)個(gè)錯(cuò),有個(gè)紅色的波浪線在下面,所以本文將給大家介紹了idea注入mapper報(bào)錯(cuò)報(bào)紅的幾種解決方案,需要的朋友可以參考下2023-12-12Java通過wait()和notifyAll()方法實(shí)現(xiàn)線程間通信
這篇文章主要為大家詳細(xì)介紹了Java通過wait()和notifyAll()方法實(shí)現(xiàn)線程間通信的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04SpringBoot+RabbitMQ方式收發(fā)消息的實(shí)現(xiàn)示例
這篇文章主要介紹了SpringBoot+RabbitMQ方式收發(fā)消息的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09Springboot+Vue+axios實(shí)現(xiàn)文章收藏功能
這篇文章主要為大家詳細(xì)介紹了Springboot+Vue+axios實(shí)現(xiàn)文章收藏功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08Java?離線中文語音文字識別功能的實(shí)現(xiàn)代碼
這篇文章主要介紹了Java?離線中文語音文字識別,本次使用springboot?+maven實(shí)現(xiàn),官方demo為springboot+gradle,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07