通過拜讀《java編程思想》中的註解篇,談談自己對註解中的理解!
學習android經常會用到註解,但是對於註解也是半懵逼狀態,至於它是怎麼來的,怎麼起作用是什麼都不知道;比如熟悉的@Override,@Deprecated……等等只知道是註解,以及其起到的作用,至於它是或不是java中的語法,怎麼由來怎麼讀取的其實是沒探究的。本文起到一個拋磚引玉的作用,探索註解的由來以及如何自定義自己的註解
一、註解是什麼
《java編程思想》的定義:註解(也被成爲元數據)爲我們在代碼中添加信息提供了一種形式化的方法,使我們可以在稍後某個時刻非常方便地使用這些數據。
看完這個定義如果是沒接觸註解的我相信很多開發者都處於懵懂狀態,也不知道怎麼用。其實具體點的就是給類、方法、屬性附加一些說明信息,等到想用的時候在讀取。而且這個信息(元數據)是同源代碼一起結合在一起的,所以可通過java代碼獲取到註解信息。
如系統的@Override:說明信息就是:指名這個方法是重載的方法;這個例子沒有值不夠形象,往下讀,等會會有例子,相信很快你就知道了
二、定義
註解的定義很想java定義接口:如
public @interface CupAnnotation {}
這樣就定義好了一個註解類,是不是特別像接口,但是與接口不一樣的是,它裏邊定義的方法可以有默認值 如:
@Target({ElementType.METHOD, ElementType.FIELD}) //方法、屬性都可以和使用註解
@Retention(RetentionPolicy.RUNTIME) //vm運行期間保留註解 通過反射機制獲取註解信息
public @interface CupAnnotation {
int id() default -1;
String color() default "white";
String shaper() default "點";
String methodName() default "defualt";
}
接口中是沒有@符號的,而且聲明的方法是不會有default ;
而註解是通過@interface來指明這是一個註解類,default “呵呵”是方法的默認值;
默認值的作用:如果有這個沒有這個默認值,則在使用註解的使用必須給其賦值,如果有默認值可以不給其賦值,會 默認使用指定的默認值。如熟悉的@Override 這就是典型的不需要指定值,使用的都是默認值
三、使用
package com.example.zwr.annotationdemo;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* author : zhongwr on 2016/12/1
* 用以杯子的註解
*/
@Target({ElementType.METHOD, ElementType.FIELD}) //方法、屬性都可以使用註解
@Retention(RetentionPolicy.RUNTIME) //vm運行期間保留註解 通過反射機制獲取註解信息
public @interface CupAnnotation {
int id() default -1;
String color() default "white";
String shaper() default "點";
String methodName() default "defualt";
}
upAnnotation(methodName = "DefualtCup of getColor()") public String getColor() { return "color = defualt"; } public String getId() { return "id = -1"; } public String getShape() { return "shaper = defualt"; }}
定義這個註解值得注意的是下邊這兩行:@Target({ElementType.METHOD, ElementType.FIELD}) //方法、屬性都可以使用註解
@Retention(RetentionPolicy.RUNTIME) //vm運行期間保留註解 通過反射機制獲取註解信息
說明它的作用,否則在運行時是無法生效的,可以查看java中用到註解的源碼,跟進去它們的定義也會有這兩個/**
* author : zhongwr on 2016/12/1
*/
public class CircleGreenCup {
@CupAnnotation(id = 1)
private int ids;
@CupAnnotation(color = "green")
private String color;
@CupAnnotation(shaper = "圓形")
private String shape;
public String getColor() {
return "color = red";
}
@CupAnnotation(methodName = "circleGreenCup of getId")
public String getId() {
return "id = 1";
}
public String getShape() {
return "shaper = 圓的";
}
}
將cup聲明爲:紅色的正方形cup/**
* author : zhongwr on 2016/12/1
* 使用聲明註解類的默認值
*/
public class SquareRedCup {
@CupAnnotation(id = 2)
private int ids;
@CupAnnotation(color = "Square")
private String color;
@CupAnnotation(shaper = "正方形")
private String shape;
public String getColor() {
return "color = red";
}
public String getId() {
return "id = 2";
}
@CupAnnotation(methodName = "SquareRedCup of getShape()")
public String getShape() {
return "shaper = 正方形";
}
}
package com.example.zwr.annotationdemo.model;
import com.example.zwr.annotationdemo.CupAnnotation;
/**
* author : zhongwr on 2016/12/1
* 使用聲明註解類的默認值
*/
public class DefualtCup {
@CupAnnotation
private int ids;
@CupAnnotation
private String color;
@CupAnnotation
private String shape;
@CupAnnotation(methodName = "DefualtCup of getColor()")
public String getColor() {
return "color = defualt";
}
public String getId() {
return "id = -1";
}
public String getShape() {
return "shaper = defualt";
}
}
@CupAnnotation(shaper = "圓形")
package com.example.zwr.annotationdemo;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* author : zhongwr on 2016/12/1
* 獲取杯子的註解
*/
public class CupAnnotationUtil {
public static String getAnnotationInfo(Class<?> targetClass) {
StringBuilder annotationInfo = new StringBuilder();
//判斷targetClass類聲明是否用了註解:如在類聲明前用了註解則可通過這個獲取類註解的value 舉例:@CupAnnotation public class Cupdemo{}
CupAnnotation cupAnnotation = targetClass.getAnnotation(CupAnnotation.class);
annotationInfo.append("類聲明用的註解:");
annotationInfo.append("\n");
annotationInfo.append("類 :" + targetClass.getName());
if (null == cupAnnotation) {
annotationInfo.append("類聲明沒用到註解 :");
annotationInfo.append("\n");
} else {
annotationInfo.append("杯子標籤:" + cupAnnotation.id() + " 杯子顏色:" + cupAnnotation.color() + " 杯子形狀:" + cupAnnotation.shaper());
}
annotationInfo.append("\n");
annotationInfo.append("方法聲明用的註解:");
annotationInfo.append("\n");
//判斷targetClass所有方法是否有用到註解
Method methods[] = targetClass.getDeclaredMethods();
if (null != methods) {
int length = methods.length;
for (int i = 0; i < length; i++) {
CupAnnotation cupMethodAnno = methods[i].getAnnotation(CupAnnotation.class);
if (null != cupMethodAnno) {//方法中使用了註解則不會爲空
annotationInfo.append("註解方法名:" + cupMethodAnno.methodName());
} else {
annotationInfo.append("沒使用註解的方法名:" + methods[i].getName());
}
annotationInfo.append("\n");
}
}
annotationInfo.append("\n");
annotationInfo.append("屬性聲明用的註解:");
annotationInfo.append("\n");
//判斷targetClass所有屬性是否有用到註解
Field[] fields = targetClass.getDeclaredFields();
if (null != fields) {
int length = fields.length;
for (int i = 0; i < length; i++) {
CupAnnotation cupFieldAnno = fields[i].getAnnotation(CupAnnotation.class);
if (null != cupFieldAnno) {//方法中使用了註解則不會爲空
annotationInfo.append("屬性註解信息:");
annotationInfo.append("\n");
annotationInfo.append("屬性名:" + fields[i].getName() + " 杯子標籤:" + cupFieldAnno.id() + " 杯子顏色:" + cupFieldAnno.color() + " 杯子形狀:" + cupFieldAnno.shaper());
} else {
annotationInfo.append("沒使用註解的屬性名:" + fields[i].getName());
}
annotationInfo.append("\n");
}
}
return annotationInfo.toString();
}
}
CupAnnotation cupAnnotation = targetClass.getAnnotation(CupAnnotation.class)
CupAnnotation cupMethodAnno = methods[i].getAnnotation(CupAnnotation.class);
CupAnnotation cupFieldAnno = fields[i].getAnnotation(CupAnnotation.class);
package com.example.zwr.annotationdemo;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import com.example.zwr.annotationdemo.model.CircleGreenCup;
import com.example.zwr.annotationdemo.model.DefualtCup;
import com.example.zwr.annotationdemo.model.SquareRedCup;
import com.example.zwr.annotationdemo.model.UnuseCupAnnotation;
public class MainActivity extends Activity implements View.OnClickListener {
private static final String TAG = "MainActivity";
private TextView tvGetAnnotationInfo;
private TextView tvShowAnnotationInfo;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
private void initViews() {
tvGetAnnotationInfo = (TextView) findViewById(R.id.tv_get_annotation_info);
tvShowAnnotationInfo = (TextView) findViewById(R.id.tv_show_annotation_info);
tvGetAnnotationInfo.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v == tvGetAnnotationInfo) {
String annotationContent = CupAnnotationUtil.getAnnotationInfo(DefualtCup.class) + "\n" +
CupAnnotationUtil.getAnnotationInfo(CircleGreenCup.class) + "\n" +
CupAnnotationUtil.getAnnotationInfo(SquareRedCup.class) + "\n" +
CupAnnotationUtil.getAnnotationInfo(UnuseCupAnnotation.class);
Log.d(TAG, annotationContent);
tvShowAnnotationInfo.setText(annotationContent);
}
}
}