黑马程序员Java培训和Android培训_java高新技术(二)

来源:互联网 发布:适合旅游的泳衣 知乎 编辑:程序博客网 时间:2024/04/28 20:09

1. 自定义注解添加属性:

package com.itcast.d34;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

 

// RetentionPolicy.RUNTIME对应内存中的字节码,RetentionPolicy.CLASS对应class文件,

// RetentionPolicy.SOURCE对应源文件

@Retention(RetentionPolicy.RUNTIME)

// 指定注解的位置

@Target({ElementType.METHOD,ElementType.TYPE})

public @interface MyAnnotation {

    String value();// 特殊的属性名,可省略的变量名

    int[] arrayAttr() default {1,2,3}; // 可设置默认值

    /* 可以是一个注解类型 */

    /* 可以是枚举类型 */

}

使用:

package com.itcast.d34;

 

@MyAnnotation("cc")

public class AnnotationTest {

    public static void main(String[] args) {

       if (AnnotationTest.class.isAnnotationPresent(MyAnnotation.class)) {

          

           MyAnnotation myAnnotation = (MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class);

           System.out.println(myAnnotation.value());

       };

    }

}  

2. 泛型

泛型的深入理解和高级应用:泛型是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合时会去掉“类型”信息,使程序运行效率不受影响,对于参数化的泛型类型,getClass()方法的返回值和原始类型完全一致。由于编译生成的字节码会去掉泛型的类型信息,只要能跳过编译器,就可以往某个泛型集合中加入其它类型的数据,例如,使用反射得到集合,再调用其add方法即可:

ArrayList<Integer> al = new ArrayList<Integer>();

       al.getClass().getMethod("add", Object.class).invoke(al, "asd");

System.out.println(al.get(0));

泛型通配符?的使用:

// 打印任意类型的泛型集合

public static void printCollection(Collection<?> collection){

              System.out.println(collection.size());

              for(Object obj : collection){

                     System.out.println(obj);

              }

       }

通配符?的扩展:

限定通配符的上边界:

正确:Vector<? extends Number> x = new Vector<Integer>();

错误:Vector<? extends Number> x = new Vector<String>();

限定通配符的下边界:

正确:Vector<? super Integer> x = new Vector<Number>();

错误:Vector<? super Integer > x = new Vector<Byter>();

限定通配符包括自己。

遍历一个泛型集合:

HashMap<String,Integer> maps = new HashMap<String, Integer>();

maps.put("zxx", 28);

maps.put("lhm", 35);

maps.put("flx", 33);

 

Set<Map.Entry<String,Integer>> entrySet = maps.entrySet();

for(Map.Entry<String, Integer> entry : entrySet){

       System.out.println(entry.getKey() + ":" + entry.getValue());

}

自定义泛型方法及其应用:

private static <T> T[] swap(T[] a,int i,int j){

       T tmp = a[i];

       a[i] = a[j];

       a[j] = tmp;

       return a;

}

只用引用类型才能作为自定义泛型方法的实际参数。swap(new int[]{1,3,5,4,5},3,4)是不对的

如果类的实例对象中的多处都要使用同一个泛型参数,即这些地方引用的泛型类型要保持同一个实际类型时,这时候就要采用泛型类型飞方式进行定义,也就是类级别的泛型,语法格式:

public class BaseDao<T>{

       private T filed;

       public void save(T obj){}

       public T findById(int id);

}

通过反射获得泛型的实际类型参数:

Method applyMethod = GenericTest.class.getMethod("applyVector", Vector.class);

Type[] types = applyMethod.getGenericParameterTypes();

ParameterizedType pType = (ParameterizedType)types[0];

System.out.println(pType.getRawType());

// 获得实际参数类型

System.out.println(pType.getActualTypeArguments()[0]);

 

public static void applyVector(Vector<Date> v1){}

编译器编译带类型说明的集合时会去掉“类型”信息,所以只能使用方式的反射。

原创粉丝点击