天天看點

注解和反射_1

p1-p9

1: 注解

1.1 注解的概念

注解和反射_1

注解:能給人看,也能給機器看 ,機器會用反射機制進行通路。

如@Override都是注解,注解具有檢查和限制的作用.如把S小寫,override就報錯了。

注解和反射_1

1.2 内置注解

注解和反射_1
package annotation;
import java.util.ArrayList;
import java.util.List;
/**
 * author liulei
 * data  5.21
 * since 1.8
 * version 1.0
 * Description  内置注解示範
 */
public class Demo01 {
    //Override  重寫的注釋
    @Override
    public String toString(){
        return super.toString();
    }
    //Deprecated 不推薦程式員使用,但是可以使用,或者存在更好的方式
    @Deprecated
    public static void test()
    {
        System.out.println("這是個不被推薦的方法");
    }
    @SuppressWarnings("all")
    public void test02()
    {
        List list = new ArrayList();
    }
    public static void main(String[] args) {
        test();
    }
}      

1.3 元注解

 自定義的注解的類型都是@interface +名字的類型

注解和反射_1
package annotation;

import java.lang.annotation.*;

/**
 * author liulei
 * data  5.21
 * since 1.8
 * version 1.0
 * Description  元注解示範
 */
@Myannotation
public class Demo02 {
    @Myannotation
    public void test()
    {
    }
    @Myannotation2(age = 18,name = "liulei")
    public void test1(){
    }
//注解如果參數沒有預設值,我們必須顯示指派
    @Myannotation3(value = "ll")
    public void test2(){
    }

}
//定義一個注解
//Target 表示注解可以用在哪些地方
//Retention 表示我們的注解在什麼地方還有效,作用的範圍
//runtime>class>source
//Documented 表示是否将注解生成在Javadoc中
//Inherited  子類可以繼承父類的注解
@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@interface Myannotation{
}
@interface Myannotation2{
    //注解的參數:參數類型+參數名();
    String name() default "";
    int age();
    int id() default -1;//如果預設為-1,代表不存在
    String[] schools() default {"西部開源","清華大學"};
}
@interface Myannotation3{
    String value();//如果隻有一個參數,則參數為value
}      

  常用的四個注解就是下面四個,其中Retention表示注解的生命周期,絕大部分情況我們聲明的注解都是運作時期間有效(RUNTIME),尤其是自帶的注解,是以我們自定義的一定要加上

Target 表示注解可以用在哪些地方,如ElementType.TYPE則表示這個注解隻能用在類上,      
注解和反射_1

2:反射

2.1 反射介紹

注解和反射_1
注解和反射_1
注解和反射_1
注解和反射_1

2.2 Class類

注解和反射_1
注解和反射_1

注解和反射_1

注解和反射_1
1 package Reflection;
 2 
 3 /**
 4  * author liulei
 5  * data 5.21
 6  * since 1.8
 7  * version 1.0
 8  * Description  擷取類對象的Class對象的幾種方法
 9  */
10 public class Test01 {
11     public static void main(String[] args) throws ClassNotFoundException {
12         Person p = new Student("abc");
13         System.out.println("這個人是:"+p.name);
14         //方式一:通過對象獲得
15         Class c1 = p.getClass();
16         System.out.println(c1.hashCode());
17         //方式二:forname獲得
18         Class c2 = Class.forName("Reflection.Student");
19         System.out.println(c2.hashCode());
20         //方式三:通過類名.class獲得
21         Class c3 = Student.class;
22         System.out.println(c3.hashCode());
23         //方式四:基本内置類型都有一個Type屬性
24         Class c4 = Integer.TYPE;
25         System.out.println(c4);
26         //獲得父類類型
27         Class c5 = c1.getSuperclass();
28         System.out.println(c5);
29     }
30 
31 }
32 class Person{
33     public String name;
34 
35     public Person(String name) {
36         this.name = name;
37     }
38     public Person() {
39     }
40 
41 }
42 class Student extends Person
43 {
44     public Student(String name) {
45         this.name = name;
46     }
47 }
48 class Teacher extends Person
49 {
50     public Teacher() {
51     }
52 
53     public Teacher(String name) {
54         this.name = "老師";
55     }
56 }      
注解和反射_1
1 package Reflection;
 2 
 3 import java.lang.annotation.ElementType;
 4 
 5 /**
 6  * author liulei
 7  * data
 8  * since 1.8
 9  * version 1.0
10  * Description
11  */
12 public class Test02 {
13     public static void main(String[] args) {
14         Class c1 = Object.class;//類
15         Class c2 = Comparable.class;//接口
16         Class c3 = String[].class;//數組
17         Class c4 = int[][].class;//二維數組
18         Class c5 = Override.class;//注解
19         Class c6 = ElementType.class;//枚舉
20         Class c7 = Integer.class;//基本資料類型
21         Class c8 = void.class;//void
22         Class c9 = Class.class;//Class
23         System.out.println(c1);
24         System.out.println(c2);
25         System.out.println(c3);
26         System.out.println(c4);
27         System.out.println(c5);
28         System.out.println(c6);
29         System.out.println(c7);
30         System.out.println(c8);
31         System.out.println(c9);
32 
33         //隻要元素類型與次元一緻,就是同一個Class
34         int[] a = new int[10];
35         int[] b =new int[100];
36         System.out.println(a.getClass().hashCode());
37         System.out.println(b.getClass().hashCode());
38 
39     }
40 }      

 2.3 類的加載

注解和反射_1

注解和反射_1
注解和反射_1

 先把class檔案加載到記憶體,靜态資料轉換為運作時資料,擷取對應的java.lang.Class,連結階段,為類變量配置設定記憶體空間,并指派預設初始值,初始化階段則是調用cinit方法合并靜态變量和靜态代碼塊并指派初始值。父類沒初始化也要初始化父類,cinit方法保證了枷鎖和同步。

1 package Reflection;
 2 
 3 /**
 4  * author liulei
 5  * data
 6  * since 1.8
 7  * version 1.0
 8  * Description
 9  */
10 public class Test03 {
11     public static void main(String[] args) {
12         A a = new A();
13         System.out.println(A.m);
14     }
15 }
16 /*
17 1 加載到記憶體,會産生一個類對應的Class對象
18 2 連結,連結結束後 m = 0
19 3 初始化
20     <clinit>()
21     {
22        System.out.println("A類靜态代碼塊初始化");
23         m = 300;
24         m = 100;
25     }
26  */
27 class A{
28     static {
29         System.out.println("A類靜态代碼塊初始化");
30         m = 300;
31     }
32     static int m = 100;
33 
34     public A() {
35         System.out.println("A類的無參構造初始化");
36     }
37 }      
注解和反射_1
注解和反射_1

過程