註解是程式的一部分
@Override 限定方法必須是重寫的方法
@Deprecated 標記一個已經過時的方法
@SuppressWarnings(「型別參數」)忽略警告
自定義一個註解
元註解:用在註解中的註解
@Target 用來定義註解的使用範圍
ElementType.ANNOTATION_TYPE 用在註解中
PACKAGE 用在包中
TYPE 用在型別上
CONSTRUCOR 用在構造方法上
FIELD 用在屬性上
METHOD 用在方法上
@Retention 用來定義註解的存在時間
RetentionPolicy.SOURCE 註解只存在於原始碼中,編譯成class的時候會丟棄註解
RetentionPolicy.CLASS 註解存在於class檔案中,在載入到JVM的時候會丟棄註解
RetentionPolicy.RUNTIME 註解在程式執行中依然存在
@Documented 註解文件化
@Inherited 是否能被子類自動繼承
MyTest
import java.lang.annotation.*;
/**
* 自定義一個註解
* 註解 Annotation
*/
@Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {
String value();
}
Teacher
public class Teacher {
@MyTest("張三")
private String name;
public void teachJava(){
System.out.println(name+"在教Java課");
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
'}';
}
}
AutoCreate
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定義建立物件的註解
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoCreate {
}
AnnotationUtil
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
/**
* 自定義註解的處理工具
*/
public class AnnotationUtil {
//解析obj物件的註解
public static void initData(Object obj){
try {
//獲得obj物件的Class物件
Class c = obj.getClass();
//獲得name屬性物件
Field name = c.getDeclaredField("name");
//獲得name屬性上的MyTest註解物件
MyTest an = name.getAnnotation(MyTest.class);
//獲得註解中的value值
String value = an.value();
//將註解中的值設定給屬性
name.setAccessible(true);
name.set(obj,value);
}catch (Exception ef){
ef.printStackTrace();
}
}
}
AutoCreateUtil
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class AutoCreateUtil {
public static void init(Object obj){
try {
//拿到Manager類的Class物件
Class c = obj.getClass();
//獲得Manager類中的teacher屬性
Field f = c.getDeclaredField("teacher");
//獲得f變數的型別的Class物件[Teacher類的Class物件]
Class c2 = f.getType();
//獲得Teacher類的無參構造方法
Constructor con = c2.getDeclaredConstructor();
//範例化物件
Object teacher = con.newInstance();
//處理Teacher的MyTest註解
AnnotationUtil.initData(teacher);
//將teacher物件作爲f的值
f.setAccessible(true);
f.set(obj,teacher);
}catch (Exception ef){
ef.printStackTrace();
}
}
}
Teachertest
public class Teachertest {
public static void main(String[] args) {
Teacher t = new Teacher();
//通過註解的方式設定屬性的值
AnnotationUtil.initData(t);
System.out.println(t);
}
}
輸出結果:
如何在多個屬性中設定指點屬性?
Manager
public class Manager {
@AutoCreate
private Teacher teacher;
@AutoCreate
private Book book;
@AutoCreate
private Book book2;
public void teach(){
System.out.println(book);
teacher.teachJava();
System.out.println(book2);
}
}
Book
public class Book {
private String name;
public Book() {
name="java";
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
'}';
}
}
AutoCreateUtil2
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class AutoCreateUtil2 {
public static void init(Object obj){
try {
//拿到Manager類的Class物件
Class c = obj.getClass();
Field[] fs = c.getDeclaredFields();
for(Field f:fs){
AutoCreate ac = f.getAnnotation(AutoCreate.class);
if(ac!=null){
//獲得f變數的型別的Class物件[Teacher類的Class物件]
Class c2 = f.getType();
//獲得Teacher類的無參構造方法
Constructor con = c2.getDeclaredConstructor();
//範例化物件
Object obj2 = con.newInstance();
//將teacher物件作爲f的值
f.setAccessible(true);
f.set(obj, obj2);
if(f.getName().equals("teacher")){
AnnotationUtil.initData(obj2);
}
}
}
}catch (Exception ef){
ef.printStackTrace();
}
}
}
ManagerTest
public class ManagerTest {
public static void main(String[] args) {
Manager m = new Manager();
AutoCreateUtil2.init(m);
m.teach();
}
}
輸出結果