java中的反射和注解

来源:互联网 发布:软件价值评估 编辑:程序博客网 时间:2024/04/27 23:35

反射:

在运行时状态,

对于任意一个类,知道这个类的属性和方法,

对于任意一个对象,访问它的任意一个属性和方法

动态获取类或者对象的信息以及动态调用对象方法

public class ReflectTest {

    /**

     * 使用反射调用公有方法,getMethod获取公有方法,类名要包含完整包名

     * @return

     */

    static int getAgeByReflectMethod(){

        int age =0;

        try {

            Class cls = Class.forName("com.qianfeng.zhouyi.xutilstest.Student");

            Object obj = cls.newInstance();

            Method setAgeMethod = cls.getMethod("setAge", int.class);

            setAgeMethod.invoke(obj,10);


            Method getAgeMethod = cls.getMethod("getAge");

            age = (int) getAgeMethod.invoke(obj);


        } catch(Exception e) {

            Log.d("LessonXutils",e.getMessage());

        }


        return age;

    }


    /**使用反射访问私用属性,getDeclaredField能获取私有或公有属性,要调用setAccessible使其可以访问

     * 

     * @return

     */

    static int getAgeByReflectField(){

        int age =0;

        try {

            Class cls = Class.forName("com.qianfeng.zhouyi.xutilstest.Student");

            Object obj = cls.newInstance();

            Field fd = cls.getDeclaredField("age");

            fd.setAccessible(true);

            fd.set(obj,10);


            age = (int) fd.get(obj);



        } catch(Exception e) {

            Log.d("LessonXutils",e.getMessage());

        }


        return age;

    }


    /**调用私有静态方法,getDeclaredMethod可以获取私有或公有方法,要调用setAccessible使其可以访问

     * 静态方法不用newInstance得到对象

     * 

     */

    static void invokeStaticMethod(){

        try {

            Class cls = Class.forName("com.qianfeng.zhouyi.xutilstest.Student");

            Method staitcMethod = cls.getDeclaredMethod("test");

            staitcMethod.setAccessible(true);

            staitcMethod.invoke(cls);

        } catch(Exception e) {

            Log.d("LessonXutils",e.getMessage());

        }


    }



}


class Student{

    private int age;

    private String name;


    public int getAge() {

        return age;

    }


    public void setAge(intage) {

        this.age= age;

    }


    public StringgetName() {

        return name;

    }


    public void setName(String name) {

        this.name= name;

    }


    private static void test(){

        Log.d("LessonXutils","invoke test by reflect");

    }

}

注解:

  • 基本注解:

   

@Override:表示当前的方法定义将覆盖父类中的方法。

@Deprecated:使用了注解为它的元素编译器将发出警告,因为注解@Deprecated是不赞成使用的代码,被弃用的代码。

@SupperssWarning 取消警告,比如@SuppressWarnings("deprecation")可以取消

@Deprecated带来的警告

  • 元注解

修饰注解的注解,用于自定义注解

@Retention 表示在什么级别保存该注解

   RetentionPolicy.SOURCE - 源代码,编译器丢弃

   RetentionPolicy.CLASS - class文件 VM丢弃

   RetentionPolicy.RUNTIME - 内存中的字节码,在VM在运行时保留注解,才能够通过反射获取注解信息

@Target - 表示注解用在什么位置

   ElementType.FIELD - 用在成员变量,用在枚举属性

   ElementType.METHOD - 用在方法上

   ElementType.TYPE - 类或者接口,或者枚举

   ElementType.PACKAGE - 用在包上

   ElementType.LOCAL_VARIABLE - 局部变量

   ElementType.PARAMETER - 参数上

  • 自定义注解的实现和使用

定义一个注解

自定义一个注解,需要先使用元注解来声明注解的保留级别和应用位置

注解中可以包含属性,跟普通属性不一样,它类似于接口中的方法,可以设置默认值返回值

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.FIELD)



public @interfaceMyAnnotation {

    int value()default 10;

    String name()default "Ann";

}

使用注解:

class Student2 {

    @MyAnnotation(name="age",value=20)

    private int age;



    public int getAge() {

        return age;

    }


    public void setAge(intage) {

        this.age= age;

    }


}

通过反射得到注解中的值:

public static void showAnnotationMsg(){

    Class cls = null;

    try {

        cls = Class.forName("com.qianfeng.zhouyi.xutilstest.Student2");

        Field ageFiled = cls.getDeclaredField("age");

        ageFiled.setAccessible(true);

        MyAnnotation ann = ageFiled.getAnnotation(MyAnnotation.class);

        Log.d("AnnotationTest",ann.name()+"\n");

        Log.d("AnnotationTest",ann.value()+"");


    } catch(Exception e) {

        Log.d("AnnotationTest",e.getMessage());

    }


}

0 0