Java中的注解和反射實(shí)例詳解
一、注解
注解(Annotation): 從jdk5.0開始引進(jìn),可以對(duì)程序進(jìn)行解釋或被其他程序讀取。
注解格式:"@注釋名",并可以添加一些參數(shù)。
例:@MyAnnotation(value=‘value')
1、內(nèi)置注解
@override: 用于修飾方法,表示該方法聲明是重寫或?qū)崿F(xiàn)一個(gè)父類的方法
@Deprecated: 用于修飾方法、屬性、類,表示已過時(shí)不建議使用的
@SuppressWarnings: 用于抑制編譯時(shí)的警告信息
2、元注解
作用:用于注解其他注解
@Target: 用于描述注解的適用范圍
例:@Target(ElementType.ANNOTATION_TYPE) 適用范圍為注解定義
@retention: 表示需要在什么級(jí)別保存該注解信息
SOURCE - 源碼級(jí)別
CLASS - class級(jí)別
RUNTIME - 運(yùn)行級(jí)別
SOURCE < CLASS < RUNTIME
例:@Retention(RetentionPolicy.RUNTIME) 此注解運(yùn)行時(shí)有效
@Documented: 表示是否將注解生成在Javadoc中
@Inherited: 表示子類可以繼承父類的注解
3、自定義注解
注解定義:@interface+注解名
@Target(ElementType.METHOD)//作用在方法上 @Retention(RetentionPolicy.RUNTIME)//運(yùn)行時(shí)有效 @interface Myannotation1{ //注解的參數(shù):參數(shù)類型 + 參數(shù)名(); String Parameter1() ; int Parameter2() default -1; //默認(rèn)值為-1代表不存在 } @Target(ElementType.METHOD)//作用在方法上 @Retention(RetentionPolicy.SOURCE )//源碼中有效 @interface Myannotation2{ String Value() ;//只有一個(gè)參數(shù)時(shí),參數(shù)名用Value }
測(cè)試:
//有默認(rèn)值的參數(shù)可以不填沒有默認(rèn)值的參數(shù)必填,并且參數(shù)填寫沒有順序 @Myannotation1(Parameter1 = "Parameter1 ") //參數(shù)定義為Value時(shí),前面的"Value = "可以省略 @Myannotation2("Value") public void test01(){ }
二、反射
反射(Reflection)是java被視為動(dòng)態(tài)語言的關(guān)鍵,反射機(jī)制允許程序在執(zhí)行期借助于Reflection API取得任何類的內(nèi)部信息,并能直接操作任意對(duì)象的內(nèi)部屬性及方法。
優(yōu)缺點(diǎn):具有靈活性但是效率較低。
Class c = Class.forName(java.lang.String)
1、Class類
某個(gè)類的屬性、方法和構(gòu)造器、某個(gè)類實(shí)現(xiàn)了哪些接口,JRE都為其保留了一個(gè)不變的Class類型的對(duì)象,同一個(gè)類的所有對(duì)象共享同一個(gè)Class對(duì)象。
Class類具有以下特點(diǎn):
- Class本身也是一個(gè)類
- Class對(duì)象只能由系統(tǒng)建立對(duì)象
- 一個(gè)加載的類在JVM中只會(huì)有一個(gè)Class實(shí)例
- 一個(gè)Class對(duì)象對(duì)應(yīng)的是一個(gè)加載到JVM中的一個(gè)class文件
- 每個(gè)類的實(shí)例都會(huì)記得自己是由哪個(gè)Class實(shí)例所生成
- 通過Class可以完整地得到一個(gè)類中的所有被加載結(jié)構(gòu)
- Class類是Reflection的根源,針對(duì)任何想動(dòng)態(tài)加載、運(yùn)行的類,唯有先獲得相應(yīng)的Class對(duì)象
Class類的常用方法:
方法名 | 功能說明 |
---|---|
static Class.forName(String name) | 返回指定類名name的Class對(duì)象 |
Object newInstance() | 調(diào)用缺省構(gòu)造函數(shù),返回Class對(duì)象的一個(gè)實(shí)例 |
getName() | 返回此Class對(duì)象所表示的實(shí)體(類、接口、數(shù)組類或void)的名稱 |
Class getSuperClass() | 返回當(dāng)前Class對(duì)象的父類Class對(duì)象 |
Class[] getinterfaces() | 返回當(dāng)前Class對(duì)象的接口 |
Class Loader getClassLoader() | 返回該類的類加載器 |
Constructor[] getConstructors() | 返回一個(gè)包含某些Constructor對(duì)象的數(shù)組 |
Method getMethod(String name ,Class T) | 返回一個(gè)Method對(duì)象,此對(duì)象的形參類型為paramType |
Field[] getDeclaredFields | 返回Field對(duì)象的一個(gè)數(shù)組 |
2、通過反射獲取Class對(duì)象:
所有的類都可以通過反射獲取其Class對(duì)象。
下面通過例子列舉獲取類的Class對(duì)象的三種方式:
//新建Person類 class Person{ String name; int age; int id; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
//測(cè)試 public class test02 { public static void main(String[] args) throws ClassNotFoundException { Person person = new Person(); //方式一、通過包名獲取 Class class1 = Class.forName("com.reflection.Person"); System.out.println(class1.hashCode()); //方式二、通過對(duì)象獲取 Class class2 = person.getClass(); System.out.println(class3.hashCode()); //方式三、通過類獲取 Class class3 = Person.class; System.out.println(class3.hashCode()); } }
輸出結(jié)果:
結(jié)論:三種方式獲取的Class對(duì)象為同一個(gè)。
3、獲取類的運(yùn)行時(shí)結(jié)構(gòu)
public class test03 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException { Class c1 = Class.forName("com.reflection.Person"); //獲得類的名字 String name = c1.getName();//獲得包名加類名 String simpleName = c1.getSimpleName();//獲得類名 //獲得類的屬性 Field[] fields = c1.getFields();//獲得類的所有公有屬性 Field[] declaredFields = c1.getDeclaredFields();//獲得類的所有屬性 Field field = c1.getField(name);//獲得類的指定公有屬性 Field declaredField = c1.getDeclaredField(name);//獲得類的指定屬性(所有類型均可) //獲得類的方法 Method[] method = c1.getMethods();//獲得本類及其父類的所有公有方法 Method[] declaredMethods = c1.getDeclaredMethods();//獲得本類的所有方法 Method getName = c1.getMethod("getName", null);//獲取指定方法(本類及其父類的所有公有方法) Method setName = c1.getDeclaredMethod("setName", String.class);//獲取指定方法(本類的所有方法) //獲得類的構(gòu)造器 Constructor[] constructors = c1.getConstructors();//獲取所有公有構(gòu)造器 Constructor[] declaredConstructors = c1.getDeclaredConstructors();//獲取所有構(gòu)造器 Constructor constructor = c1.getConstructor(String.class, int.class);//獲取指定公有構(gòu)造器 Constructor declaredConstructor = c1.getDeclaredConstructor(String.class, int.class);//獲取指定構(gòu)造器 } }
4、通過反射構(gòu)造對(duì)象
public class Test04 { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { //獲得Class對(duì)象 Class c1 = Class.forName("com.reflection.Person"); //通過反射創(chuàng)建對(duì)象 Person person = (Person)c1.newInstance();//本質(zhì)上是調(diào)用了無參構(gòu)造器 Constructor constructor = c1.getDeclaredConstructor(String.class,int.class);//獲取有參構(gòu)造器 Person person2 = (Person) constructor.newInstance("name",18);//調(diào)用有參構(gòu)造器創(chuàng)建對(duì)象 //通過反射調(diào)用普通方法 Method setName = c1.getDeclaredMethod("setName", String.class);//獲取方法 setName.invoke(person,"name");//通過invoke調(diào)用方法 //通過反射操作屬性 Field name = c1.getDeclaredField("name");//獲取name屬性 name.setAccessible(true);//關(guān)閉安全檢測(cè),關(guān)閉后可以訪問私有屬性(true為關(guān)閉,false為打開,默認(rèn)是false) name.set(person,"lalala");//設(shè)置屬性的值 } }
5、通過反射獲取注解的信息
創(chuàng)建類和注解
@Testclass("db_Student2")//類注解 //創(chuàng)建學(xué)生類 class Student2{ @Testfield(columnname = "name",type = "varchar",length = 20)//屬性注解 String name; @Testfield(columnname = "age",type = "int",length = 3) int age; @Testfield(columnname = "ID",type = "int",length = 10) int ID; public Student2() { } public Student2(String name, int age, int ID) { this.name = name; this.age = age; this.ID = ID; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getID() { return ID; } public void setID(int ID) { this.ID = ID; } } //類的注解 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interface Testclass{ String value(); } //屬性的注解 @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @interface Testfield{ String columnname(); String type(); int length(); }
測(cè)試
public class test05 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException { Class c1 = Class.forName("com.zjrcu.reflection.Student2"); //通過反射獲得注解 Annotation[] annotations = c1.getAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation); } //通過反射獲得注解value的值 Testclass testclass = (Testclass)c1.getAnnotation(Testclass.class); String value = testclass.value(); System.out.println(value); //獲取類中指定注解的value值 Field f = c1.getDeclaredField("name"); Testfield testfield = (Testfield) f.getAnnotation(Testfield.class); System.out.println(testfield.columnname()); System.out.println(testfield.length()); System.out.println(testfield.type()); } }
總結(jié)
到此這篇關(guān)于Java中的注解和反射的文章就介紹到這了,更多相關(guān)Java注解和反射內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java 算法之希爾排序詳解及實(shí)現(xiàn)代碼
這篇文章主要介紹了java 算法之希爾排序詳解及實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2017-03-03SpringBoot處理大量請(qǐng)求數(shù)據(jù)的傳輸問題的方法小結(jié)
在Spring?Boot項(xiàng)目常常需要中處理大量請(qǐng)求數(shù)據(jù)的傳輸問題,這篇文章主要為大家整理了一些常用的方法,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-01-01Java網(wǎng)絡(luò)編程UDP實(shí)現(xiàn)消息發(fā)送及聊天
這篇文章主要為大家詳細(xì)介紹了Java網(wǎng)絡(luò)編程UDP實(shí)現(xiàn)消息發(fā)送及聊天,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07解決idea services窗口不見的一種特殊情況(小白采坑系列)
這篇文章主要介紹了解決idea services窗口不見的一種特殊情況(小白采坑系列),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-09-09springboot @Controller和@RestController的區(qū)別及應(yīng)用詳解
這篇文章主要介紹了springboot @Controller和@RestController的區(qū)別及應(yīng)用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11詳解Spring注入集合(數(shù)組、List、Map、Set)類型屬性
這篇文章主要介紹了詳解Spring注入集合(數(shù)組、List、Map、Set)類型屬性,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01