day26基礎加強(泛型、萬用字元、註解、反射 註解使用)
阿新 • • 發佈:2018-11-19
泛型 1、具有一個或多個泛型變數的型別被稱之為泛型類 class A<T>{} 2、在建立泛型類例項時,需要為其型別變數賦值 A<String> a = new A<String>(); 如果建立例項時,不給型別變數賦值,那麼會有一個警告。 3、泛型方法:具有一個或多個型別變數的方法,稱之為泛型方法 class A<T>{ public T fun(T t1){ } } fun()方法不是泛型方法,是泛型類中的一個方法 public <T>T fun (T t1){} -->是泛型方法 泛型方法和泛型類沒什麼關係,泛型方法不一定非要在泛型類中。 4、泛型在類中或方法中的使用 泛型類中使用泛型 成員型別 返回值和引數型別 區域性變數的引用上 class A<T>{ private T bean;//泛型可在成員變數上使用 public T fun(T t){}//泛型可以在類中的方法上(返回值和引數型別)使用 public void fun2(){//泛型還可以在區域性變數的引用型別上使用 T b=... new T();//不行 } } 5、泛型的繼承和實現 class A<T>{} class AA extends A<String>{}//不是泛型類,只是他爸爸是泛型類 5.1、繼承泛型類 子類不是泛型類:需要給父類傳遞型別常量 當給父類傳遞的型別常量為String時,那麼在父類中所有T都會被String替換 子類是泛型類,可以給父類傳遞型別常量,也可以傳遞型別變數 class AA1 extends A<Integer>{} class AA3<E> extends A<E>{} 泛型的萬用字元 1、萬用字元使用的場景 方法的形參 2、萬用字元的優點 使方法更加通用 3、萬用字元分類 無界通配:? 子類限定:? extend Object 父類限定: ? super Integer 4、萬用字元缺點 使變數使用上不再方便 無界:引數和返回值為泛型的方法,不能使用 子類:引數為泛型的方法不能使用 父類:返回值為泛型的方法不能使用 5、比較萬用字元 boolean addAll(Collection<E> c) List<Number> numList = new ArrayList<Number>(); List<Integer> intList = new ArrayList<Integer>(); numList.addAll(intList);//addAll(Collection<Number> c),傳遞的是List<Integer> boolean addAll(Collection<? extends E> c) List<Number> numList = new ArrayList<Number>(); List<Integer> intList = new ArrayList<Integer>(); numList.addAll(intList);//addAll(Collection<? extends Number> c),傳遞的是List<Integer> 註解【配置檔案 需要有人讀 否則無意義,往往是框架讀比如tomcat】 1、什麼是註解 語法:@註釋名稱 註解的作用:替代xml配置檔案 servlet3.0中,就可以不再使用web.xml,而是所有配置都使用註解 註解是由框架來讀取使用 2、註解 定義註解類:框架的工作 使用註釋:我們的工作 讀取註釋(反射):框架的工作 3、定義註解類 class A{} interface A{} enum A{} @interface A{} 所有的註解都是Annotation的子類 4、使用註解 可以把註解作用在:類、方法、屬性、構造器、方法引數、區域性變數也可以把註解作用在包上[沒啥用] @Retention(RetentionPolicy.RUNTIME) public @interface MyAnn{} 下面的程式碼會出錯 @MyAnn package xx; public class A{} 因為java不讓這麼註解包,如果想給包添加註解必須再建立一個檔案:package-info.java檔案,然後在這個方法中給出對包的註解 package-info.java @MyAnn package xx 反射包上的註解 Package p = Package.getPackage("my.xx"); MyAnn myAnn = p.getAnnocation(MyAnn.class); 註解的作用目標 類 方法 構造器 引數 區域性變數 包 5、註解的屬性 定義屬性 格式:型別 屬性名(); @interface MyAnno1{ int age(); String name(); } 使用註解時給屬性賦值 @MyAnno1(age=10,name="zhangSan") 註解屬性的預設值:在定義註解時,可以給註解定義預設值 int age() default 100; 在使用註解時,可以不給帶有預設值的屬性賦值 名為value的屬性的特權 當使用註解時,如果只(僅一個的時候)給名為value的屬性賦值時,可以省略"value=", 例如@MyAnno1(value="hello")可以書寫成@MyAnno1("hello") 註解屬性的型別 8中基本型別 String Enum Class 註解型別 以上型別的一維陣列型別 包裝類不行比如Integer 當給陣列型別的屬性賦值時,若陣列元素的個數為1時,可以省略大括號 @MyAnno1( a=100, b="hello", c=MyEnum1.A, d=String.class,
[email protected](aa=1,bb="2"), f={"a","b"}, h=100 ) public class Demo3 { } @interface MyAnno1{ int a(); String b(); MyEnum1 c(); Class d(); MyAnno2 e(); String[] f(); int[] h(); } @interface MyAnno2{ int aa(); String bb(); } //列舉要求是其中的一個 enum MyEnum1{ A,B,C } 6、註解的作用目標限定以及保定策略限定 6.1讓一個註解,它的作用目標只能在類上,不能在方法上,這就叫作用目標的限定 在呼叫註解時,給註解添加註解,這個註解是@Target 列舉就幾個選項 @Target(value={ElementType.TYPE,ElementType.METHOD,ElementType.FIELD}) @interface MyAnno1{ } 6.2保留策略 原始碼檔案(source):註解只在原始碼中存在,當編譯時就被忽略了 位元組碼檔案(class):註解在原始碼中存在,然後編譯時會把註解資訊放到了class檔案,但JVM在載入類時,會忽略註解 JVM中(runtime):註解在原始碼、位元組碼檔案中存在,並且在JVM載入類時,會把註解載入到JVM內中(唯一可反射的註解) 6.3、限定註解的保留策略 使用 @Retention(RetentionPolicy.RUNTIME) @interface MyAnno1{ } 7、讀取註解(反射) 反射泛型資訊 Class-->Type getGenericSupperclss() Type-->ParameterizedType:把Type強轉成ParameterizedType型別 ParameterizedType-->引數化型別=A<String> ParameterizedType:Type[] getActuallTypeArguments(),A<String>中的String Type[]就是Class[],就得到了型別引數 abstract class A<T>{ public A(){ /* * 獲取子類傳遞的泛型資訊,得到一個class */ // Class clazz = this.getClass();//得到子類的型別 // Type type = clazz.getGenericSuperclass();//獲取傳遞給父類的引數化型別 // ParameterizedType pType = (ParameterizedType) type;//就是A<String> // Type[] types = pType.getActualTypeArguments();//就是一個Class陣列 // Class c = (Class) types[0];//就是String // Class c = null; // System.out.println(c.getName());//String或Integer Class c= (Class) ((ParameterizedType) this.getClass().getGenericSuperclass()) .getActualTypeArguments()[0]; System.out.println(c.getName()); } } 反射註解 1、要求 註解的保留策略必須是RUNTIME 2、反射註解需要從作用目標上返回 類上的註解,需要使用Class獲取 方法上的註解,需要Method來獲取 構造器的註解,需要Constructor來獲取 成員上的,需要Field來獲取 Class: Method、Constructor、Field:AccessibleObject 都有一個方法: Annotation getAnnotation(Class):返回目標上指定型別的註解 Annotation[] getAnnotations:返回目標上所有註解