黑马程序员--22--高新技术(三)

------- android培训java培训、期待与您交流! ----------

n  注解 1.5  annotation

注解就相当与一种标记,在程序中加了注解就等于为程序打上了某种标记,

以后javac编译器,开发工具和其他程序可以用反射来了解这个类及各种元素上有无何种标记,看有你又什么标记就去干相应的事。标记可以加在包,类,字段,方法的参数以及局部变量上。

 

1@SuppressWarning 取消显示指定的编译器警告

2@Deprecated 过时

3@Override 重载

 

注解的应用结果图:

 

 

 

l  自定义注解及其应用

1、定义最简单的注解

public @interface ItcastAnnotation {}

2、把它加到某个类上

@ItcastAnnotation//注解的一个对象

public class AnnotationTest1

3、利用反射进行测试 这个类上是否有注解@ItcastAnnotation

       if(AnnotationTest1.class.isAnnotationPresent(ItcastAnnotation.class)){

      ItcastAnnotation annotation = (ItcastAnnotation)AnnotationTest1.class.getAnnotation(ItcastAnnotation.class);

      System.out.println(annotation);

}

 

4@Retention 的三种取值(枚举值):RetentionPolicy.SOURCERetentionPolicy.CLASSRetentionPolicy.RUNTIME  分别对应:java源文件—>calss文件—>内存中的字节码

@Override ---java源文件,SOURCE

@ SuppressWarning-- java源文件,SOURCE

@ Deprecated--- RUNTIME 

 

  retention 元注解,用于说明注解的生命周期,默认值在.class阶段

5@Target  用于说明注解能用于哪个成分上

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

      java.lang.annotation -- ElementType

l  为注解增加基本属性

1、定义基本类型的属性和应用属性

String color() default "blue";//缺省属性blue

     

  

 

2、用反射获得注解对应的实例对象后,再通过该对象调用属性对应的方法

3、 ItcastAnnotation annotation = (ItcastAnnotation)AnnotationTest1.class.getAnnotation

(ItcastAnnotation.class);

   System.out.println(annotation.color());

4、为属性指定缺省值   default "blue";

5value属性

 String Value();

 如果注解中只设置一个value属性,其他属性采用默认值,可以省略“value=
6、数组类型的属性

       int[] arrayAttr() default{3,4};

7、枚举类型的属性

       EnumTest.TrafficLamp lamp()

default EnumTest.TrafficLamp.RED;

8、注解类型的属性

       MetaAnnotation anntationAttr() default @MetaAnnotation("ddd");

9、注解属性的返回值类型

  8个原始类型、字符串类型、Classannotationenum、包括前面类型是数组

注意:在程序中创建注解的实例对象,直接用@带上标记即可

 

 

 

u  泛型

没有使用泛型时,只要是对象,不管什么类型,都可以存储进同一个集合中。使用泛型集合,可以讲集合中的元素限定为一个特定类型,集合中只能存储同一个类型的对象,这样更安全,并且从集合中获取一个对象时,编译器也可以知道这个对象的类型,不需要进行强制类型转换。

 

       泛型时提供给javac编译器使用的,可以限定集合中的类型,让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合时会去掉“类型“信息,使程序运行效率不受影响。由于编译生成的字节码会去掉泛型的类型信息,只要跳过编译器,就可以往某个泛型集合中加入其他类型的数据。例如:用反射得到集合,在调用add方法。

 

一、术语:

1、整个称为ArrayList泛型类型

2ArrayList 中的E称为类型变量或类型参数

3、整个ArrayList 称为参数化的类型

4ArrayListInteger称为类型参数的实例或实际类型参数

5ArrayList中的<>typeof

6ArrayList称为原始类型

二、参数化类型与原始类型的兼容性

         Vector v = new Vector(); //警告,

         Vector v = new Vector(); //警告

三、参数化类型不考虑类型参数继承关系:

   Vector v = new Vector(); //错误,不写object没错

 Vector v = new Vector(); //错误,不写object没错

 

四、创建数组实例时,数组元素不能使用参数化的类型(编译器不允许创建类型变量的数组)

       Vector vectorList[] = new Vector[10];

思考题:

Vector v1= new Vector();

Vectorv =v1;

//编译器严格按照语法检测的工具  一句一句翻译

 

五、?通配符

  使用?通配符可以引用其他各种参数化的类型,?通配符定义的变量主要用作引用,可以调用与参数无关的方法,不能调用与参数有关的方法。

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

      //collection.add("abc"); 不能调用与类型有关的方法

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

      for(Object obj:collection){

        System.out.println(obj);

      }

      collection = new HashSet<Date>();//正确

     

   }

 

六、通配符的扩展

1、限定通配符的上边界

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

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

2、限定通配符的下边界

       Vector<? supper Integer > x = new Vector< Number >();//正确

注意:限定通配符总是包括自己

 

Class<?> y;

Class<String> x;

y=x; //正确

x=y;//错误

u  泛型集合的综合案例

 

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

      map.put("zhangsan", 23);

      map.put("f", 32);

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

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

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

      }

 

u  自定义泛型方法

Java中的泛型类型类似于c++中的模板,但这种相识仅限于表面。Java语言中的泛型基本上完全是在编译器中用于编译器执行检查和类型推段,然后生成非泛型的字节码,这种实现技术称为擦除。扩展虚拟机指令集支持泛型认为是无法接受的。

 

1、用于放置泛型的类型参数的尖括号应出现在方法的其他所有修饰符之后和在方法返回类型之前,也就是紧邻返回值之前,类型参数通常用单个大写字母表示。

2、只有引用类型才能作为泛型方法的实际参数,对与add方法,使用基本类型的数据进行测试没有问题,因为会自动装箱和拆箱。Swap(int[],1,2)会报错,是因为编译器不会对int[3]中的int自动拆箱和装箱,因为int[3]本身已经是对象了。

 

private static <T> T add(T x,T y) {

      return null;

   }

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

      T tmp = a[i];

      a[i] = a[j];

      a[j] = tmp;

   }

3、除了在应用泛型时可以使用extends限定符,在定义泛型时也可以使用extends限定符,并且可以用&来指定多个边界。

例如:<V extends Serializable&cloneble> void method(){}

4、普通方法、构造方法和静态方法中都可以使用泛型。

5、编译器不允许创建类型变量的数组。

6、异常采用泛型

 Public static <T extends Exception > sayHello() throws T{

       Try {}catch( Exception e){ throw (T)e;}}

7、在泛型中可以同时有多个类型参数,在定义他们的尖括号用逗号分开。

例如:public static <K,V> V getValue(K key){return map.get(key)}

 

u  自定义泛型类型

如果类的实例对象中的多处都要用到同一个泛型参数,即这些地方引用的泛型类型要操持同一个实例类型时,就要采用泛型类型的方式进行定义。

语法格式:public class Genoric<T>{

       Private T field1;

      Public void save( T obj){}

       Public T getById(int id){return T}

}

 

注意:

1、在对泛型类型进行参数化时,类型参数的实例必须是引用类型,不能是基本类型。

2当一个变量被声明为泛型时,只能被实例变量和方法调用(还有内嵌类型),

而不能被静态变量和静态方法调用,因为静态成员是被所有参数化的类所共享的,所以静态成员不应该有类级别的类型参数。(静态方法可以使用方法级别的泛型)静态成员不用创建对象就可以调用。(对象的类型)

 

u  通过反射获得泛型的参数化类型

通过变量自身是没法知道它的泛型,当把变量交给方法作为参数或者返回值去使用时,方法类提供了一些方来获得参数列表,并且以泛型类型获得参数列表。(就是获得方法接受参数的实际类型)

方法类上有相应的方法:getGenericReturnType()获得泛型的返回类型

\getGenericParameterTypes 获得泛型的参数类型

GetParameterTypes() 获得参数列表

 

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

     

   }

 

 

   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]);

 

 

 

 

------- Windows Phone 7手机开发.Net培训、期待与您交流! -------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值