Java学习笔记十一

只要做好准备,人生的尽头也是一段绝美的旅程。——尤金·奥凯利

今日整理记录内容:
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();
        }

学习心得:观看资料–》思考问题–》实践证明–》整理记录 = 有思想的技术大牛!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章