JDK提供的注解
@SuppressWarnings("deprecation") 消除警告
@Deprecated 用在方法上 设置该方法过时
@override 重写方法上的注解
注解的原理:
注解相当于一种标记,在程序上加了注解就等于为程序打上了某种标记,没加,则等于没有标记。其他程序可以利用反射来了解你的类及各种元素上有无任何标记,看你有什么标记,就去干相应的事。标记可以加在包、类、字段、方法、方法的参数、以及局部变量上。
注解的应用结构图
注解的开发流程
注解类、应用了注解类的类、对应用注解类的类进行反射操作的类
@Retention(RetentionPolicy.RUNTIME) 元注解:标识注解保留时期 RUNTIME 注解保留到运行时期
@Target({ElementType.METHOD,ElementType.TYPE})
@interface A{
String color();
int[] arrs(); default {3,4,4};
EnumTest.TrafficLamp lamp() default EnumTest.Traffic.RED;
MetaAnnotation annotionArr() default @MetaAnnotion("zhangpeng");
}
@A(color="red")
Class B{
}
Class C{
if(B.class.isAnnotionPresent(A.class)){
A a=B.class.getAnnotion(A.class);
//访问注解属性
a.color();
a.arrs().length;
a.lamp().nextLamp().name();
a.annotationArr().value();
}
}
注解有三个阶段:
java源文件阶段---class文件阶段---内存中字节码阶段
泛型
泛型是提供给javac使用的,可以限定集合中的存储类型,让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合时会去除掉"类型"信息,使程序运行效率不受影响。泛型就是给编译器看的,因此通过反射机制可以绕过编译器。
ArrayList<E> E就是类型参数、类型变量
ArrayList<String> 成为参数化类型 ,意思已经增加过参数了。
数组是不能参数化的,也就是说,数组不能用泛型。
泛型中的通配符
①.?
//遍历任何参数化类型的集合
public static void list(ArrayList<?> list){
for(Object obj:list){
}
list.add("String");//这样会报错,因为该list不知道自己该匹配什么类型的数据
list.size();//这样不会报错,因为size()和类型参数无关。
}
总结:使用?通配符可以引用其他各种参数化类型,?通配符定义的变量主要用作引用,可以调用与参数化无关的方法,不能调用与参数化有关的方法。
②.?通配符的扩展
限定通配符的上边界
ArrayList<? extends Number> X=new ArrayList<Integer>(); 仅限于Number或者Number的子类
限定通配符的下边界
ArrayList< ? super Integer> Y =new ArrayList<Integer>(); 仅限于Integer的父类或者Integer
定义泛型方法(在方法上定义泛型)
public static <T>void zhangpeng(T a,T b){//返回值前必须声明一个类型,表示你要使用的泛型的参数类型
}
备注:只要引用类型才能用作泛型方法的参数,如果遇到int之类的参数,只是被装箱成Integer的缘故。
如:
public static <T> void zhangpeng(T[] a,T[] b){
}//这个方法会报错,因为T对应的是int类型,而这个int不能被装箱。
定义泛型类型(在类上定义泛型)
例如:
一个类中有两个泛型方法,但是这两个方法没有制约,比如我要开发一个dao,我希望save一只狗,find出来的也是一只狗,但是如果是定义两个泛型方法,save一只狗,find出来很有可能是一只猪,因为二个方法并无制约。但是要想做到制约,所以必须在类上定义泛型了。
public class BaseDao{
public <T>void save(T param){
}
public <T> T find(int param){
}
}
改为:
public class BaseDao<T>{
public void save(T t){
}
public T find(int id){
}
}
枚举
待续...