23-java基础加强(反射、泛型、注解、动态代理)
一、反射
1. 一段java代碼在程序運(yùn)行期間會(huì)經(jīng)歷三個(gè)階段: source-->class-->runtime
??? Person.java—Person.class? à? 類(lèi)加載到內(nèi)存 Person.class –> 創(chuàng)建對(duì)象 程序運(yùn)行
?
2. Class 對(duì)象
??? 在java中用一個(gè)Class對(duì)象來(lái)表示一個(gè)java類(lèi)的class階段
??? Class對(duì)象封裝了一個(gè)java類(lèi)中定義的成員變量、成員方法、構(gòu)造方法、類(lèi)名、包名等
?
3. 反射
??? 反射就是獲得一個(gè)java類(lèi)的各個(gè)組成部分
??? 對(duì)第二個(gè)階段進(jìn)行解析
?
4. 反射的用法
??? 1)需要獲得java類(lèi)的各個(gè)組成部分,首先需要獲得代表java類(lèi)的 Class 對(duì)象
??? 獲得Class對(duì)象的三種方式:
??? Class.forName(classname) 用于做類(lèi)加載
??? obj.getClass()????????????? 用于獲得對(duì)象的類(lèi)型
??? 類(lèi)名.class?????????????? ??? 用于獲得指定的類(lèi)型,傳參用
??? Person.class String.class int.class? int[].class void.class
?
??? 2) 反射類(lèi)的成員方法
??? Class clazz = Person.class;
??? Method method = clazz.getMethod(methodName, new Class[]{paramClazz1, paramClazz2});
??? method.invoke();
???
??? 3) 反射類(lèi)的構(gòu)造函數(shù)
??? Constructor con = clazz.getConstructor(new Class[]{paramClazz1, paramClazz2,...})
??? con.newInstance(params...)
?
??? 4) 反射類(lèi)的屬性
??? Field field = clazz.getField(fieldName);
??? field.setAccessible(true);? // 由于屬性私有就不能直接訪(fǎng)問(wèn)了,所以需要取消java的訪(fǎng)問(wèn)權(quán)限檢查
??? field.setObject(value);
??? field.getObject();
?
5. 反射用在哪里
??? 到底框架是什么?? 框架就是將開(kāi)發(fā)中大量重復(fù)的代碼集中起來(lái)寫(xiě)個(gè)通用的程序
??? 框架就是用反射來(lái)實(shí)現(xiàn)的
??? 框架是一個(gè)通用的程序,這個(gè)程序是無(wú)法運(yùn)行的,是缺少零部件的,零部件需要將來(lái)使用框架的人組裝進(jìn)來(lái)
??? 框架需要現(xiàn)在的類(lèi)調(diào)用將來(lái)寫(xiě)的類(lèi)
?
??? 框架是將來(lái)的程序員調(diào)用的,框架不能實(shí)現(xiàn)完整的功能,框架只是一些一些通用的代碼
??? 框架要運(yùn)行一定會(huì)依賴(lài)將來(lái)寫(xiě)的類(lèi)
??? 現(xiàn)在寫(xiě)的類(lèi)要調(diào)用將來(lái)寫(xiě)的類(lèi),我們先針對(duì)接口進(jìn)行調(diào)用,將來(lái)的類(lèi)需要實(shí)現(xiàn)接口,那么方法就固定了
??? 但是將來(lái)寫(xiě)的類(lèi)的類(lèi)名我們無(wú)法獲知,這時(shí)就需要調(diào)用者通過(guò)配置文件告訴框架具體的類(lèi)名
?
二、 泛型
1. 泛型是一種可變化的類(lèi)型
??? 類(lèi)型不確定,需要調(diào)用者來(lái)指定
???
2. 用途:
??? 一個(gè)類(lèi)的多個(gè)成員方法用到的參數(shù)類(lèi)型或返回值類(lèi)型都是未知的類(lèi)型,但又需要是同一個(gè)類(lèi)型,就可將方法的
??? 參數(shù)類(lèi)型定義為泛型,此泛型必須在類(lèi)上先予以聲明才能在方法中使用
?
??? 一個(gè)方法的多個(gè)參數(shù)和返回值需要是同一個(gè)類(lèi)型,也可以用泛型來(lái)解決,在返回值前面聲明泛型
?
3. 泛型的基本概念
以L(fǎng)ist<E>為例:<>念著typeof 例, List<String> 就是 List typeof String
List<E>中的E稱(chēng)為類(lèi)型參數(shù)變量???? 方法定義參數(shù)形式參數(shù)?
List<Integer>中的Integer稱(chēng)為實(shí)際類(lèi)型參數(shù)
整個(gè)List<E>稱(chēng)為泛型類(lèi)型?? GenericType
整個(gè)List<Integer>稱(chēng)為參數(shù)化的類(lèi)型
?
?
4. 泛型的使用
??? 1)使用帶泛型的類(lèi)時(shí),在創(chuàng)建對(duì)象時(shí)可以為泛型指定實(shí)際類(lèi)型參數(shù),指定的具體類(lèi)型相當(dāng)于給泛型傳參
??? 2)子類(lèi)在繼承父類(lèi)的時(shí)候,可以為父類(lèi)定義的泛型指定實(shí)際類(lèi)型參數(shù)
??? class B<T>
??? class A extends B<String>
??? 通過(guò)子類(lèi)A獲得的父類(lèi)類(lèi)型就是一個(gè)參數(shù)化的類(lèi)型
??? 3)調(diào)用方法時(shí)傳入?yún)?shù)的具體類(lèi)型將作為方法中泛型的實(shí)際類(lèi)型
?
三、注解
1. jdk中自帶的三個(gè)注解
??? @Deprecated 聲明方法已過(guò)時(shí)
??? @SuppressWarnings? 取消編譯器警告
??? @Override? 聲明方法是繼承自父類(lèi)
?
2.? 什么是注解
??? 注解就是java代碼中的特殊標(biāo)記,它用于告訴調(diào)用者類(lèi)應(yīng)該如何被運(yùn)行
??? 注解相當(dāng)于配置文件的功能
?
3. 自定義注解
使用 @interface 關(guān)鍵字可以聲明一個(gè)注解
public @interface MyAnnotation1
?
注解中可以定義屬性
String name default “aaa”;
?
value是注解中的特殊屬性
注解中定義的屬性如果名稱(chēng)為 value, 此屬性在使用時(shí)可以省寫(xiě)屬性名
?
4.元注解? 元Annotation
元注解簡(jiǎn)單理解為 注解的注解
類(lèi)似于描述一個(gè)注解的信息的配置文件
@Retention 指定注解的作用域
RetentionPolicy.SOURCE
RetentionPolicy.CLASS? default
RetentionPolicy.RUNTIME
?
@Target:指定注解用于修飾類(lèi)的哪個(gè)成員.
@Target 包含了一個(gè)名為 value,類(lèi)型為ElementType的成員變量。
?
@Inherited: 被它修飾的 Annotation 將具有繼承性.
如果某個(gè)類(lèi)使用了被 @Inherited 修飾的 Annotation, 則其子類(lèi)將自動(dòng)具有該注解
?
5. 反射注解
??? 在程序可以通過(guò)反射來(lái)獲取注解中封裝的值
?
四、動(dòng)態(tài)代理
我們可以為某一個(gè)對(duì)象生成一個(gè)代理對(duì)象
代理對(duì)象要和被代理的對(duì)象實(shí)現(xiàn)同樣的接口
代理對(duì)象的方法被調(diào)用時(shí),我們可以做一些動(dòng)作,再去調(diào)用真正被代理對(duì)象的方法
在代理對(duì)象中對(duì)用戶(hù)的權(quán)限進(jìn)行檢查
?
所有的過(guò)濾器都可以用代理模式來(lái)解決
?
總結(jié)
以上是生活随笔為你收集整理的23-java基础加强(反射、泛型、注解、动态代理)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 立秋什么时候吃西瓜?
- 下一篇: 吃夜宵是什么意思?