注解
(向上转型,向下转型见Animal Man测试)
Animal类:
public class Animal {
public void say(){
System.out.println("Animal is singing!");
}
public void jump(){
System.out.println("Animal is jumping");
}
}
Man类:
public class Man extends Animal {
public void say(){
System.out.println("Man is saying!");
}
public void Man_jump(){
System.out.println("Man is jumping");
}
}
测试:
Animal a=new Man();//a指向子类的对象 ,由于向上转型a会遗失与父类不同的对象(a不可以调用Man_jump方法,该方法被遗失)
a.say();
//向上转型体现了类的多态性,增强了程序的简洁性。特点:可以不用辨别子类的具体类型而使用公用的方法
a.jump();//调用父类的jump方法(Animal的jump方法)
/*向下转型*/
//转型成功
Man man=(Man)a;
man.say();
/*转型失败案例 因为an指向的是一个Animal对象因此转化为子对象时会失败,前者成功是因为a指向的是一个Man子类对象
Animal an=new Animal();
Man mn=(Man)an;
mn.say();
*/
//解决方案
Animal an=new Animal();
if(an instanceof Man){//确定其类型
Man mn=(Man)an;
mn.say();
}
前面的基础复习到此为止,下面言归正传开始注解
注解作用:
1.读懂别人代码框架代码
2.让编程更加方便
注解:java提供的一种原程序中的元素关联任何信息和任何元数据的途径和方法
jdk自带注解:@Override @Deprecated @Suppvisewarnings
@Deprecated 过时
@Suppvisewarnings("Deprecated")//忽略该警告
注解分类:(1)源码注解(在源码中存在CLASS中不存在)
(2)编译注解(源码和class文件中均存在jdk自带注解)
(3)运行时注解(spring中自带注解)
按照来源分类:(1)来自jdk注解
(2)来自第三方的注解
(3)自定义注解
元注解 给注解定义的注解(自定义注解)
自定义注解语法要求:@interface定义注解
1.成员无参无异常形式声明
2.default可以设定默认值,成员的类型是受限的,合法的类型包括原始类型以及String Class Annotation Enumeration
3.如果注解只有一个成员,则该成员必须取名为value()(否则不符合规定但无异常) 在使用时可以忽略成员名和赋值号(=)
4.注解类可以没有成员没有成员的注解为标识注解
Target(作用域):ElementType.METHOD(修饰方法),ElementType.TYPE(修饰类) ElementType.FIELD(修饰参数)
Retention(生命周期)
RetentionPolicy.SOURCE 注解将被编译器丢弃
RetentionPolicy.CLASS 注解在class文件中可用,但会被VM丢弃
RetentionPolicy.RUNTIME VM将在运行期也保留注释,因此可以通过反射机制读取注解的信息。
Inherited(允许继承)
Documented(生成java doc时会包含注解信息)
解析注解:通过反射获取类,函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑
@Inherited 只在class上起作用可以继承在接口和方法
自定义注解实例:
Description注解的创建:
package zhujie;
import java.lang.annotation.*;
/**
* 自定义注解
*/
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Description{
//成员变量定义
String desc();
String author();
int age()default 18;
}
注解的使用:
package zhujie;
/**
* 类上的注解方法上的注解
*/
@Description(desc="prase annotation on class test",author = "ruanjianlin",age=20)
public class MetaAnnotations {
@Description(desc="prase annotation on method test",author = "ruanjianlin",age=20)
public void say(){
}
}
调用测试:
package zhujie;
import java.lang.reflect.Method;
/**
* 注解调用
*/
public class PraseAnnotations {
public static void main(String args[]){
//类加载器加载类
try {
Class c=Class.forName("zhujie.MetaAnnotations");
//找到类上面的注解
boolean isExist=c.isAnnotationPresent(Description.class);//判断是否存在该注解
if(isExist){
//拿到注解实例
Description d=(Description)c.getAnnotation(Description.class);
System.out.println(d.desc()+","+d.author()+","+d.age());
}
//找到方法上的注解
Method[]me=c.getDeclaredMethods();
for (Method method:me
) {
boolean isExist2=method.isAnnotationPresent(Description.class);//判断是否存在该注解
if(isExist2){
//拿到注解实例
Description d=(Description)method.getAnnotation(Description.class);
System.out.println(d.desc()+","+d.author()+","+d.age());
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
运行结果:
prase annotation on class test,ruanjianlin,20
prase annotation on method test,ruanjianlin,20
下篇博客(请再学习上篇关于反射博客与本篇后再浏览):小型项目:模拟hebrinate持久化层
步骤及原理:
与数据库作映射 建立Table(表注解) Column(属性注解)注解
然后通过解析注解获得表名字段名
然后通过反射取到getMethod
然后反射调用该方法