java注解的使用
2016-11-30 11:53
225 查看
大家好,今天来写一篇有关java注解相关知识,以及对注解的一些简单运用,希望对你有所帮助。
首先来了解下注解的基本语法吧,java官方提供元注解四种:Target、Retention、Documented、Inherited,在声明注解时用于描述自身,其中Target和Retention基本都会用到。
@Target表示我们想要作用在什么地方
1.CONSTRUCTOR:构造器
2.FIELD:成员变量
3.LOCAL_VARIABLE:局部变量
4.METHOD:方法
5.PACKAGE:包
6.PARAMETER:方法参数
7.TYPE:类、接口(包括注解类型) 或enum声明
其中METHOD,FIELD,PARAMETER较常使用
@Retention 在哪一个级别可用
1.SOURCE:源文件中保留
2.CLASS:在class文件中保留
3.RUNTIME:运行时保留,配合反射较常使用
@Documented
可以生成注释文档
@Inherited
这个我也不太懂什么意思,没字面理解大概是可以被继承,较少使用。
再说下注解参数的可支持数据类型,即我们常用的 @xxx(此处的类型)
1.所有基本数据类型(int,float,boolean,byte,double,char,long,short)
2.String类型
3.Class类型
4.enum类型
5.Annotation类型
6.以上所有类型的数组
如果只有一个参数的话命名最好是value(),后可跟一个默认值不加也可以,区别是没有默认值的话在使用的时候必须传入参数,而如果定义了默认值则可以不用传参。如:int value() default -1;
我们常见的应用方式如中@InjectView(参数),解释下这这句代码的意思,@InjectView代表注解类或者说注解对象吧,来看下怎么声明一个注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface InjectView {
int value() default -1;
}@Retention和@Target我们上面已经解释过了,这里的作用域是成员变量且在运行时保留,int value() default -1;代表声明一个int类型的参数,value为参数名,default -1表示一个默认值可以去掉,需要注意的是不使用默认值的话在应用时必须添加参数,而有默认值的话可不添加参数即使用@InjectView()亦可,多个参数按照同样的方式声明即可,参数若只有一个的话最好以value命名,有多个的话命名随意。我们也经常看到无参注解,这种类型为标记注解,如声明在某个方法上表示此处应做特殊处理。想要知道我们类中何处使用了注解就要通过反射了
下面准备了两个小例子实际运用,一个java、一个android,看了之后相信你们也会觉得很简单,代码中添加了注释,方便阅读。
java小例子
package annot;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by luojing on 2016/11/29.
*/
@Target(ElementType.METHOD)//声明使用在方法上
@Retention(RetentionPolicy.RUNTIME)//运行时保留
public @interface Annotation { //声明注解
//可以定义默认值也可以不写,注意String不能用null做默认值。
String name() default "";
int age() default -1;
}
打印结果:
获取到的name是:luobo--age是:20
获取到的name是:heihei--age是:-1
----------------------------------------------------------------------------------------------------------------------
由于我是做android的,也会经常用到一些开源的注解框架,借此附上一个简单的Android注解demo,省略一大堆findViewById()。
当然优秀的第三方注解框架已经不是简单的通过反射设置了,如butterknife是在编译时解析,生成相关辅助java类,效率更高且不占用cpu。我这里只是简单运用下方便学习。
MainActivi
4000
ty 布局文件中声明一个TextView,一个ImageView,调用注解工具类解析,然后直接设置数据。
package example.luojing.annotationdemo.annot;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by luojing on 2016/11/30.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface InjectView {
int value() default -1;
}
package example.luojing.annotationdemo;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
import android.widget.TextView;
import example.luojing.annotationdemo.annot.InjectView;
import example.luojing.annotationdemo.utils.InjectUtil;
/**
* Created by luojing on 2016/11/30.
* 使用注解省略findViewById()
*/
public class MainActivity extends AppCompatActivity {
@InjectView(R.id.tv_title)
public TextView tvTitle;
@InjectView(R.id.iv_content_pic)
public ImageView ivContentPic;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
InjectUtil.inject(this);
setData();
}
private void setData() {
tvTitle.setText("文字设置成功");
ivContentPic.setImageResource(R.drawable.beautiful_girl);
}
}
以上大致如此,若有不对的地方请指正,希望对你有帮助。
首先来了解下注解的基本语法吧,java官方提供元注解四种:Target、Retention、Documented、Inherited,在声明注解时用于描述自身,其中Target和Retention基本都会用到。
@Target表示我们想要作用在什么地方
1.CONSTRUCTOR:构造器
2.FIELD:成员变量
3.LOCAL_VARIABLE:局部变量
4.METHOD:方法
5.PACKAGE:包
6.PARAMETER:方法参数
7.TYPE:类、接口(包括注解类型) 或enum声明
其中METHOD,FIELD,PARAMETER较常使用
@Retention 在哪一个级别可用
1.SOURCE:源文件中保留
2.CLASS:在class文件中保留
3.RUNTIME:运行时保留,配合反射较常使用
@Documented
可以生成注释文档
@Inherited
这个我也不太懂什么意思,没字面理解大概是可以被继承,较少使用。
再说下注解参数的可支持数据类型,即我们常用的 @xxx(此处的类型)
1.所有基本数据类型(int,float,boolean,byte,double,char,long,short)
2.String类型
3.Class类型
4.enum类型
5.Annotation类型
6.以上所有类型的数组
如果只有一个参数的话命名最好是value(),后可跟一个默认值不加也可以,区别是没有默认值的话在使用的时候必须传入参数,而如果定义了默认值则可以不用传参。如:int value() default -1;
我们常见的应用方式如中@InjectView(参数),解释下这这句代码的意思,@InjectView代表注解类或者说注解对象吧,来看下怎么声明一个注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface InjectView {
int value() default -1;
}@Retention和@Target我们上面已经解释过了,这里的作用域是成员变量且在运行时保留,int value() default -1;代表声明一个int类型的参数,value为参数名,default -1表示一个默认值可以去掉,需要注意的是不使用默认值的话在应用时必须添加参数,而有默认值的话可不添加参数即使用@InjectView()亦可,多个参数按照同样的方式声明即可,参数若只有一个的话最好以value命名,有多个的话命名随意。我们也经常看到无参注解,这种类型为标记注解,如声明在某个方法上表示此处应做特殊处理。想要知道我们类中何处使用了注解就要通过反射了
下面准备了两个小例子实际运用,一个java、一个android,看了之后相信你们也会觉得很简单,代码中添加了注释,方便阅读。
java小例子
package annot;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by luojing on 2016/11/29.
*/
@Target(ElementType.METHOD)//声明使用在方法上
@Retention(RetentionPolicy.RUNTIME)//运行时保留
public @interface Annotation { //声明注解
//可以定义默认值也可以不写,注意String不能用null做默认值。
String name() default "";
int age() default -1;
}
package annot; /** * Created by luojing on 2016/11/29. * 随便写的一个类用于测试 */ public class AnnotationTest { //单个参数且命名为value时无需用=连接,直接填入值即可 @Annotation(name = "luobo", age = 20) private void get() { } //不写参数的使用默认值,没有默认值的话必须添加参数 @Annotation(name = "heihei") public void post() { } }
package annot; import java.lang.reflect.Method; /** * Created by luojing on 2016/11/29. * 调用测试 */ public class AnotationDemo { public static void main(String[] args) { try { //使用反射获取到class对象 Class<?> clazz = Class.forName("annot.AnnotationTest"); //获取类中声明的所有方法 Method[] declaredMethods = clazz.getDeclaredMethods(); if (declaredMethods.length >= 1) { for (Method method : declaredMethods) { //method.getAnnotation(参数为定义的注解类的class对象) Annotation annotation = method.getAnnotation(Annotation.class); if (annotation != null) { //通过注解中的方法获取到值 String name = annotation.name(); int age = annotation.age(); System.out.println("获取到的name是:" + name + "--age是:" + age); } } } } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
打印结果:
获取到的name是:luobo--age是:20
获取到的name是:heihei--age是:-1
----------------------------------------------------------------------------------------------------------------------
由于我是做android的,也会经常用到一些开源的注解框架,借此附上一个简单的Android注解demo,省略一大堆findViewById()。
当然优秀的第三方注解框架已经不是简单的通过反射设置了,如butterknife是在编译时解析,生成相关辅助java类,效率更高且不占用cpu。我这里只是简单运用下方便学习。
MainActivi
4000
ty 布局文件中声明一个TextView,一个ImageView,调用注解工具类解析,然后直接设置数据。
package example.luojing.annotationdemo.annot;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by luojing on 2016/11/30.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface InjectView {
int value() default -1;
}
package example.luojing.annotationdemo.utils; import android.app.Activity; import android.view.View; import java.lang.reflect.Field; import example.luojing.annotationdemo.annot.InjectView; /** * Created by luojing on 2016/11/30. */ public class InjectUtil { public static void inject(Activity activity) { //获取class对象 Class<? extends Activity> clazz = activity.getClass(); try { // 通过反射获取类中的public成员变量,还有一个getDeclaredFields(), // 区别是这个可以获取到所有访问权限符修饰的变量, // 若要得到非public修饰的变量需调用setAccessible(true)进行暴力访问, // Method、Annotation、Constructor中也是如此区分。 Field[] fields = clazz.getFields(); //遍历数组 for (Field field : fields) { //判断该成员变量是否使用了注解,参数是我们自定义的注解类 if (field.isAnnotationPresent(InjectView.class)) { //获取到自定义注解对象 InjectView annotation = field.getAnnotation(InjectView.class); //获取我们设置的值,如 @InjectView(R.id.xxx) //和上面一步可以简写成 field.getAnnotation(InjectView.class).value(); int value = annotation.value(); //...经常写的代码 View view = activity.findViewById(value); //也可以通过反射获取 //Method method = clazz.getMethod("findViewById", int.class); //View view = (View) method.invoke(activity,value); //通过反射给View赋值 field.set(activity,view); } } } catch (IllegalAccessException e) { e.printStackTrace(); } } }
package example.luojing.annotationdemo;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
import android.widget.TextView;
import example.luojing.annotationdemo.annot.InjectView;
import example.luojing.annotationdemo.utils.InjectUtil;
/**
* Created by luojing on 2016/11/30.
* 使用注解省略findViewById()
*/
public class MainActivity extends AppCompatActivity {
@InjectView(R.id.tv_title)
public TextView tvTitle;
@InjectView(R.id.iv_content_pic)
public ImageView ivContentPic;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
InjectUtil.inject(this);
setData();
}
private void setData() {
tvTitle.setText("文字设置成功");
ivContentPic.setImageResource(R.drawable.beautiful_girl);
}
}
以上大致如此,若有不对的地方请指正,希望对你有帮助。
相关文章推荐
- EasyDBO中Java注解配置映射的原理及使用
- 在EasyDBO中使用Java注解配置映射的原理及使用
- 关于在struts2中使用java注解报异常 java.lang.reflect.InvocationTargetException
- @深入注解,在Java中设计和使用自己的注解
- Java自定义注解Annotation的使用
- 在EasyDBO中使用Java注解配置映射的原理及使用
- 黑马程序员---java几个基本的注解的使用
- 高阶Java-Java注解 Java annotation 使用详解
- Java基础-学习使用Annotation注解对象
- @深入注解,在Java中设计和使用自己的注解
- 在EasyDBO中使用Java注解配置映射的原理及使用
- 在EasyDBO中使用Java注解配置映射的原理及使用
- 在EasyDBO中使用Java注解配置映射的原理及使用
- JUnit 4 使用 Java 5 中的注解(annotation)
- java5.0使用annotion注解
- 在EasyDBO中使用Java注解配置映射的原理及使用
- 在EasyDBO中使用Java注解配置映射的原理及使用
- 在EasyDBO中使用Java注解配置映射的原理及使用
- 使用java5的注解和Sping/AspectJ的AOP 来实现Memcached的缓存
- 黑马程序员---java几个基本的注解的使用