1. 程式人生 > 實用技巧 >java註解和反射

java註解和反射

註解(Annotation)

註解入門

  • 註解是從jdk5.0開始引入

  • 註解的作用:

    可以對程式作出解釋

    可以被其他程式讀取

  • 註解的格式:@註解名

  • 註解可以在package,class,method等上面,相當於給他們添加了額外的輔助資訊

內建註解

  1. @Override,用於修飾方法,表示該方法重寫

  2. @Deprecated,用於修改方法,屬性,類,表示不建議使用這樣的元素,已過時

  3. @SuppressWarnings,用來抑制編譯時的警告資訊,需要新增一個引數

    @SuppressWarnings("all") @SuppressWarnings("unchecked")等等

元註解

//定義一個註解
//Target表示註解可以用在那些地方  方法,類和介面
@Target(value = {ElementType.METHOD,ElementType.TYPE})
​
//Retention表示註解在什麼地方有效
//routime>class<sources
@Retention(value = RetentionPolicy.RUNTIME)
​
//表示我們的註解生成在javadoc中
@Documented
​
//子類可以繼承父類的註解
@Inherited
@interface MyAnnoation{
​
}

自定義註解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; ​ public class Test01 { ​ //顯式賦值name,不賦值預設為"",如果沒用預設值則必須要給name賦值 @MyAnnotation(name="dd",school = {"zha","xer"}) public void test(){} ​ //可以不用寫引數名,預設為value @MyAnnoation2("空間")
public void test2(){} } ​ @Target(value = {ElementType.TYPE,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation{ ​ //註解的引數:引數型別+引數名() String name() default ""; int age() default 0; String[] school(); } ​ @Target(value = {ElementType.TYPE,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @interface MyAnnoation2{ String value(); }

反射(Reflection)

反射是java被視為動態語言的關鍵

反射機制允許程式在執行期藉助於Reflection API取得任何類的內部資訊,並能給直接和操作物件的內部屬性及方法

正常方式:引入需要的包---new例項化----取得例項化物件

反射方式:例項化物件---getClass()方法---得到完整的包類名稱

package com.henry.reflect;
​
public class TestReflect {
    public static void main(String[] args) throws ClassNotFoundException {
​
        //通過反射獲取類的class物件
        Class c1 = Class.forName("com.henry.reflect.User");
        Class c2 = Class.forName("com.henry.reflect.User");
​
        //一個類在記憶體中只有一個class物件,c1和c2的hashcode相同
        //一個類被載入後,類的整個結構都會被封裝在class物件中
        System.out.println(c1.hashCode());
        System.out.println(c2.hashCode());
    }
}
​
//實體類
class User{
    private String name;
    private int id;
    private int age;
​
    public User() {
    }
​
    public User(String name, int id, int age) {
        this.name = name;
        this.id = id;
        this.age = age;
    }
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
​
    public int getId() {
        return id;
    }
​
    public void setId(int id) {
        this.id = id;
    }
​
    public int getAge() {
        return age;
    }
​
    public void setAge(int age) {
        this.age = age;
    }
​
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", id=" + id +
                ", age=" + age +
                '}';
    }
}

獲取Class類的例項

  1. Class c1 = Person.class

  2. Class c2 = person.getClass()

  3. Class c3 = Class.forName("demo.Person")

//測試class類的建立方式
public class TestGetClass {
    public static void main(String[] args) throws ClassNotFoundException {
        Person person = new Student();
        System.out.println(person.name);
​
        //方式1,通過物件獲得class
        Class c1 = person.getClass();
        System.out.println(c1.hashCode());
​
        //方式2,forname
        Class c2 = Class.forName("com.henry.reflect.Student");
        System.out.println(c2.hashCode());
​
        //方式3 類名.class
        Class c3 = Student.class;
        System.out.println(c3.hashCode());
​
        //獲得父類型別
        System.out.println(c1.getSuperclass());
    }
}
​
class Person{
    public String name;
​
    public Person() {
    }
​
    public Person(String name) {
        this.name = name;
    }
​
​
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                '}';
    }
}
​
class Student extends Person{
    public Student(){
        this.name = "學生";
    }
}
​
class Teacher extends Person{
    public Teacher(){
        this.name = "老師";
    }
}

哪些型別有Class物件

  1. class,類

  2. interface 介面

  3. 陣列

  4. enum 列舉

  5. annotation 註解

  6. 基本資料型別

  7. void

Class c1 = Object.class; //類
Class c2 = Runnable.class; //介面
Class c3 = int[].class; //陣列
Class c4 = Override.class; //註解
Class c5 = ElementType.class; //列舉
Class c6 = Integer.class; //基本資料型別
Class c7 = void.class;

只要元素型別一樣,就是同一個Class

類載入記憶體分析