只要做好準備,人生的盡頭也是一段絕美的旅程。——尤金·奧凱利
今日整理記錄內容:
1、(JDK1.5)註解
2、(JDK1.5)泛型
一、(JDK1.5)註解
1、註解就是讓程序在編譯的時候檢測代碼的性質(正確性、過時性等),加不同的註解,編譯期檢測不同的性質;
2、常用於定義框架;
3、常用註解 Override、Deprecated、SuppressWarnings。
4、Retention:保留註解,共分三個階段(三個常量)
@Retention(RetentionPolicy.SOURCE)—》java文件
@Retention(RetentionPolicy.CLASS)—》保留到編譯時(class文件)
@Retention(RetentionPolicy.RUNTIME)—》保留到運行時
5、定義註解的屬性:返回值類型(不能沒有返回值) 方法名() default 默認值。注意:方法名字是value的屬性、返回值是數組的屬性。
解釋:
/*定義的枚舉類*/
public enum MyEnum {
MATH,ENGLISH,CHINESE;
}
/*自定義的註解類*/
@Retention(RetentionPolicy.RUNTIME)//這是定義要把MyAnnocation註解保留到運行期間
@Target({ElementType.TYPE, ElementType.METHOD})//這是定義MyAnnocation作用在方法和類型上。
public @interface MyAnnocation {
int value();//當註解中只有一個方法且方法名是value的,則在初始化時可以省略方法名
String[] getStrArr();//返回值爲數組類型的,有多個元素使用{元素1,元素2,......},如果數組中只用一個元素可省略大括號 {},
String hsDefault() default "我是默認值,可有可沒有";//這是有默認值的,在初始化註解類時,如果不賦值就是用默認值
MyEnum getEnum(); //這是返回值爲枚舉類型的
}
/*自定義註解類的使用*/
//此時註解作用到類型上,是符合要求的
@MyAnnocation(getEnum = MyEnum.MATH,
hsDefault = "這是帶有默認值的方法", //這裏是用自己設置的值代替默認值,如果不設置就是使用默認值
getStrArr = { "元素1", "元素2" }, //這裏數組中有多個元素,所以要用大括號括起來。
value = 22)
public class AnnocationTest {
@MyAnnocation(getEnum = MyEnum.ENGLISH,
/*這裏不設置有默認值的方法也是可以得*/
getStrArr = "只有一個元素"/*這裏數組中只有一個元素,所以可以省略大括號*/,
value = 22)
public static void testAnnocation(){
}
public static void main(String[] args){
/*我們通過反射技術獲得類上的註解*/
System.out.println("類上的註解:");
Annotation[] a1 = AnnocationTest.class.getAnnotations();
for (Annotation annotation : a1) {
if(annotation instanceof MyAnnocation){
MyAnnocation myA1 = (MyAnnocation)annotation;
String[] retArray = myA1.getStrArr();
int length = retArray.length;
for(int i = 0; i < length; i++){
System.out.println(retArray[i]);
}
System.out.println(myA1.getEnum().name());
System.out.println(myA1.hsDefault());
System.out.println(myA1.value());
}
}
/*我們通過反射技術獲得方法上的註解*/
try {
System.out.println("方法上的註解:");
Method method = AnnocationTest.class.getDeclaredMethod("testAnnocation", null);
Annotation[] a2 = method.getAnnotations();
for (Annotation annotation : a2) {
if(annotation instanceof MyAnnocation){
MyAnnocation myA1 = (MyAnnocation)annotation;
String[] retArray = myA1.getStrArr();
int length = retArray.length;
for(int i = 0; i < length; i++){
System.out.println(retArray[i]);
}
System.out.println(myA1.getEnum().name());
System.out.println(myA1.hsDefault());
System.out.println(myA1.value());
}
}
} catch (NoSuchMethodException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
輸出結果:
類上的註解:
元素1
元素2
MATH
這是帶有默認值的方法
22
方法上的註解:
只有一個元素
ENGLISH
我是默認值,可有可沒有
22
以上就是自定義註解類以及對於自定義註解類的使用。我們可以自己動手嘗試將@Retention的值設置成RetentionPolicy.SOURCE或RetentionPolicy.CLASS,然後運行查看結果。
動手查看Override、Deprecated、SuppressWarnings註解類的源代碼,看看如何使用。最後結合百度看看每個註解是幹什麼用的就可以了。
//Override類
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
//Deprecated類
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
//SuppressWarnings類
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
二、(JDK1.5)泛型
1、是提供給編輯器使用的,給某事物加了指定類型的泛型後,編輯器就會在源程序中阻止非指定類型的數據加入。當編譯器編譯源代碼生成.class文件時,就會將泛型<> “擦去”,也就是說反譯.class文件後“看不到”泛型了。
2、這裏所說的 “擦去”、“看不到”,是想法上的,實際上還是會存在,這是會以一種特殊標記的方式存在,某些反編譯器(jd-gui反編譯器)還是可以通過反編譯.class文件得到帶有泛型的源代碼。
3、
ArrayList<E> 整個稱爲泛型類型
ArrayList<E>中的E稱爲類型變量或類型參數
ArrayList<Integer>整個稱爲參數化的類型
ArrayList<Integer>中Integer稱爲類型參數的實例化或實際類型參數
ArrayList稱爲原始類型
4、參數化類型不考慮類型參數的繼承關係。
Vector<String> v = new Vector<Object>();//錯誤
Vector<Object> v = new Vector<String>();//錯誤
5、泛型類型使用了泛型的通配符(?)後,泛型類型的對象不能調用與類型參數有關的方法。
例: Collection<?> cl = new Collection();
cl.add(1);//錯誤,調用了與類型參數有關的方法。
解釋:
獲得某個方法的參數列表(參數列表中有泛型類型)中的實際類型參數
public class GenericTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
Method method = GenericTest.class.getDeclaredMethod("testGeneric", Vector.class, String.class);
Type[] ty1 = method.getGenericParameterTypes();
for (Type type : ty1) {
if(type instanceof ParameterizedType){
ParameterizedType pty1 = (ParameterizedType)type;
System.out.println(pty1.getTypeName());
System.out.println(pty1.getOwnerType());//獲得頂層類型。如果當前類型爲頂層,則返回null。
System.out.println(pty1.getActualTypeArguments()[0]);
System.out.println(pty1.getRawType());
}
}
} catch (NoSuchMethodException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*帶有泛型類型的方法*/
public static void testGeneric(Vector<Date> vc, String str){
}
}
輸出結果:
java.util.Vector<java.util.Date>
null
class java.util.Date
class java.util.Vector
//通過反射技術實現向參數化類型的泛型類型中增加不同類型的數據
/*定義一個實際類型參數爲String的泛型類型*/
Collection<String> collection = new ArrayList<String>();
collection.add("字符串1");//向其中增加字符串類型數據
try {
/*通過反射技術實現增加不同類型*/
Method methodAdd = collection.getClass().getMethod("add", Object.class);
methodAdd.invoke(collection, 1);
methodAdd.invoke(collection, true);
System.out.println("集合長度:"+collection.size());
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
學習心得:觀看資料–》思考問題–》實踐證明–》整理記錄 = 有思想的技術大牛!