注解
注解是jdk1.5出现在新的特性,现在框架strues,Hibernate,SpringMVC,Spring都有使用
注解其实也是一个类,别的类通过调用注解,来得到注解中的属性,进行相应的类之间的操作(传值,去除警告,定义注解使用范围)
注解可以加到类,方法,属性上面
@Deprecated() //表示此类或方法不建议使用或过时的,如果要使用的话,编译器会报警告 在使用注解的类中使用和定义注解时使用
@SuppressWarnings("deprecation") //压制过时警告 在使用注解的类中使用
@Override //覆盖父类的方法 要和父类完全一样,如果不一样编译器会报错 在使用注解的类中使用
@Retention({RetentionPolicy.CLASS,RetentionPolicy.RUNTIME}) //指示注释类型的注释要保留多久,如果注解中不存在 Retention 注释,默认RetentionPolicy.CLASS
一共有三个值 此注解只可以在定义的注解中使用
RetetionPolicy.SOURCE //保留源文件,到编译结束时去除
RetentionPolicy.CLASS //保留到class文件,到类加载完时去除
RetentionPolicy.RUNTIME //保留到内存中,在运行完程序后去除
@Target({ElementType.METHOD,ElementType.PACKAGE,ElementType.TYPE}) //指明注解的使用区域可以在方法,包,类,属性上使用 此注解只可以在定义的注解中使用
自定义注解
String color(); 为注解添加一个属性
String color() default "aa"; 在定义注解时,为注解属性设定默认的值
注解名字 annotion();// 定义一个注解的属性,返回值为一个注解
注解传值
如果注解只有一个属性为value那么可以这样写(value="deprecation") 也可以这样(deprecation") 如果多个属性的话必须要写属性的名字
如果注解属性为组织的话需要这样写(属性名={RetentionPolicy.CLASS,RetentionPolicy.RUNTIME})
注解属性的值可以是:
八个原始类型(int long double float byte short boolean void )
注解类型 :Annotation
数组类型:String[]
类类型:Class
枚举类型:Enum
练习示例:
检查某个注解是否在当前类上
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Retion {
String color() ;
Class aa();
}
Retion(color = "aa",aa=Demo22.class)
public class Userinfo {
public Userinfo() {
super();
}
private String id;
private String username;
private String password;
范型:
常用用法:
为了限定向集合或数组添加指类类型的数据,在遍历输出的时候可以不用再强制类型转换
List<String> a = new ArrayList();
a.add("aa"); // 只能添加 String类型的。如果添加别的会报异常
for (String e : a) {
System.out.println(e); // 在这里不需要强制类型转换
}
范型在编辑器通过后去去类型化
List<String> a = new ArrayList();
List<Integer> b = new ArrayList();
System.out.println(a.getClass()==b.getClass()); true
所以如果通过反射的方式的话,可以在编译完后再向本类型添加(非指定类型的值)
参数化类型不考虑继承的
如
ArrayList<Object> a = new ArrayList<String>(); 这样是会报错的
在看文档的时候
<U> Class<? extent U> 当前要使用的范型类型要继承指定类型自U
<U> Class<? supper Integer> 当前要使用的范型必须是Supper的父类
使用示例:
Map<String, String> map = new HashMap();
map.put("a", "aa");
map.put("b", "bb");
map.put("c", "cc");
Set<Map.Entry<String, String>> set = map.entrySet();
for (Entry<String, String> entry : set) {
System.out.println(entry.getKey()+" "+entry.getValue());
}
疑问:
map.entrySet();和map.keySet(); 有什么不一样除了遍历出来一个是实体。一个是值以外
自定义范型的类型 反回值前面定义一个<T> 这时传入的值的最大公约数是什么类型,则定义的T也就是什么类型
public <T> T add(Object obj){
}
上面是对方法的范型自定义
对类的范型的自定义
如果对一个类操作,比如数据库的增删改查(通用类),Dao类操作的对象为不确定对象。就可以以T代替 传入的对象是什么,那么当前dao类的对象操作的对象就是什么类型(对这个对象的所有方法都可用)
示例:
public class Demo36Dao<T> {
public void Save(T t) {
}
public void Delete(T t) {
}
public void Delete(int id) {
}
public void Update(T t) {
}
public T find(T t) {
return null;
}
}
这时传入一个什么类,那么Dao类的对象就对这个类进行操作,调用别的方法也是对传入的对象操作
public static void main(String[] args) {
Demo36Dao<Userinfo> d = new Demo36Dao<Userinfo>();
Userinfo u = new Userinfo();
d.Save(u);
}
取得方法中范型参数中范型的类型(比如取得List<String> 中的范型的参数 方便再次调用这个方法向其中传入参数)
Method m = Vector.class.getMethod("applyVertor",Vertor.class);
m.getGenericParameterTypes() ;