前言:Android目前行情确实大不如以前了,看到群里一群人在水群,都在讨论转行啊,说实话,确实有时候会有点迷茫,但是只要不忘初心,努力奋斗,肯定会有回报的~所以,还是加油吧~
写这篇博客的目的主要就是回顾一下java基础,大神可以直接飘过哈~~
1. 什么是Annotation(注解)?
JDK1.5开始,java增加了对元数据(即类的组成单元数据)的支持,也就是注解(annotation),它是代码里做的特殊标记,这些标记可以在编译、类加载、运行时在不改变原有的逻辑的情况下,被读取,并执行相应的处理,通过使用注解,我们可以在源文件中嵌入一些补充信息。代码分析工具,开发工具和部署工具可以通过这些补充休息进行验证或者部署。annotation类似于修饰符一样被使用,可以用于包、类、构造方法、方法、成员变量、参数,局部变量的声明。
这里要注意了:
- Annotation是一个接口
- java.lang.Annotation接口。
说了这么多概念性的东西,那么注解在哪用到呢??下面我们就来说说系统中自带的三个注解。
2、系统中常见的三种注解
在jdk1.5之后,在系统中提供了三个Annotaion,分别是:@Override、@Deprecated、@SuppressWarnings.
@Override
表示当前的方法将覆盖超类的方法。如果你不小心写错了方法名对不上被覆盖的方法,那么编译器会发出错误的提示。
比如我们要重写toString方法写错了名字:
@Deprecated
表示这个类或者方法已经不再建议使用了,标记为过时。
我们把类中一个方法标记为过时:
@SuppressWarnings
表示关闭不当的编译器警告信息。
比如我们用user的say(过时方法):
如果要去掉黄色警告的话:
好啦~~!了解了我们常见的几种注解后,我们来自定义一个注解~~
3、自定义Annotation
注解实现需要三个步骤:
- 编写注解
- 在类上应用注解
对应用了注解的类进行反射操作。
自定义注解的语法如下:
访问修饰符+@interface Annotation名称{
}
例如:
package com.yasin.annotation;
public @interface MyAnnotation {
}
然后我们就可以用起来了~~~
package com.yasin.annotation;
@MyAnnotation
public class User {
private String name;
private String gender;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Deprecated
public void say(){
System.out.println("i'm "+name+"i'm "+gender);
}
@Override
public String toString() {
// TODO Auto-generated method stub
return super.toString();
}
}
可以看到,我们的注解虽然用起来了,但是没有一点点作用啊,感觉~~~好啦! 接下来我们来定义注解中的变量。
4、在Annotation中定义变量
package com.yasin.annotation;
public @interface MyAnnotation {
public String name();
public String info() default "Hello EveryBody!";
}
定义变量后,在调用此Annotation时必须设置变量值,不然会报错。
调用此注解:
package com.yasin.annotation;
@MyAnnotation(name = "Yasin")
public class User {
private String name;
private String gender;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Deprecated
public void say(){
System.out.println("i'm "+name+"i'm "+gender);
}
@Override
public String toString() {
// TODO Auto-generated method stub
return super.toString();
}
}
因为info我们给了一个默认的值,所以就不需要必须定义info属性了。
public @interface MyAnnotation {
String name();
String info() default "Hello EveryBody!";
}
通过default指定变量的默认值。
除了我们这里定义的String类型外,我们的属性值还可以为:
一个数组:
String []habbies();
或者还可以是一个枚举:
EnumGender gender()default EnumGender.MALE;
public enum Gender{
MALE;FEMALE
}
4、Retention和RetentionPolicy
Annotation要决定其作用的范围,通过@Retention指定,而Retention指定的范围由RetentionPolicy决定,RetentionPolicy指定了三种范围:
范围 | 描述 |
---|---|
@Retention(RetentionPolicy.SOURCE) | 在java源程序中存在 |
@Retention(RetentionPolicy.CLASS) | 在java生成的class中存在 |
@Retention(RetentionPolicy.RUNTIME) | 在java运行的时候存在 |
如我们前面介绍的系统的三种常见的注解:@override….即为RetentionPolicy.SOURCE类型,在源程序中才存在,不然编译过不了。
5、反射与Annotation
一个Annotation真正起作用,必须结合反射机制,在反射中提供了以下的操作方法:
以下方法为Class类的方法:
方法名称 | 描述 |
---|---|
isAnnotationPresent(MyAnnotation.class); | 判断是否是指定的annotation |
@Retention(RetentionPolicy.CLASS) | 在java生成的class中存在 |
public Annotation[]getAnnotation | 得到这了类中全部注解 |
当然,这是获取类中的注解的方法,如果需要方法、变量中的注解,我们还是需要利用反射拿到method对象或者Field对象然后获取注解,好啦!!我就不特殊说明了,小伙伴自己去看api,我们会在下面的例子中给出。。。
package com.yasin.annotation;
import java.lang.annotation.Annotation;
public class Test {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
User user=new User();
//获取User类镜像
Class<?> clazz=user.getClass();
// Annotation[] annotations = clazz.getAnnotations();
// for (Annotation annotation : annotations) {
//
// }
//判断当前class是否支持MyAnnotation注解
if(clazz.isAnnotationPresent(MyAnnotation.class)){
//获取类中的MyAnnotation注解
MyAnnotation annotation = clazz.getAnnotation(MyAnnotation.class);
//获取MyAnnotation注解中的name属性
String name = annotation.name();
//获取MyAnnotation注解中的info属性
String info = annotation.info();
user.setName(name);
System.out.println(name);
System.out.println(info);
}
}
}
打印结果:
好啦~~! 注解的基础知识我们差不多掌握了,但是小伙伴又疑问了,这有毛用啊??
可如果我这样写的话,小伙伴在android是否觉得很熟悉呢?
@ViewInject(R.id.id_tradingpwddetails_pic)
private ImageView iv_cardImg;
@ViewInject(R.id.id_tradingpwddetails_name)
private TextView tv_cardName;
@ViewInject(R.id.id_tradingpwddetails_no)
private TextView tv_cardNo;
@ViewInject(R.id.id_tradingpwddetails_ssv)
private SlideSwitchView ssv_open;
@ViewInject(R.id.id_tradingpwddetails_pwd)
private View viewTBypWD;
又或者这样:
/**
* 点击事件
*/
@OnClick({
R.id.id_tradingpwddetails_setting,
R.id.id_tradingpwddetails_update
})
public void OnClick(View view) {
int id = view.getId();
if (id == R.id.id_tradingpwddetails_setting) {
} else if (id ==
}
}
是不是很熟悉呢???没错!!就是我们常见的一些android中的注解框架,下一节中我们就实现一下它~~~~