java基础 反射注解

注解和反射

注解

1.什么是注解?

Annotation是从JDK5.0开始引入的新技术.

Annotation的作用:
不是程序本身,可以对程序作出解释.(这一点和注释(comment)没什么区别)可以被其他程序(比如:编译器等)读取. 还有检查和约束的作用

Annotation的格式:
注解是以"@注释名"在代码中存在的,还可以添加一些参数值﹐例如:@SuppressWarnings(value=“unchecked”).

Annotation在哪里使用?
可以附加在package , class , method , field等上面,相当于给他们添加了额外的辅助信息,我们可以通过反射机制编程实现对这些元数据的访问

@Override:定义在java.lang.Override 中,此注释只适用于修辞方法﹐表示一个方法声明打算重写超类中的另一个方法声明.

2.内置注解

@Override:定义在java.lang.Override 中,此注释只适用于修辞方法﹐表示一个方法声明打算重写超类中的另一个方法声明.

@Deprecated :定义在java.lang.Deprecated中,此注释可以用于修辞方法﹐属性,类,表示不鼓励程序员使用这样的元素,通常是因为它很危险或者存在更好的选择.

@suppressWarnings:定义在java.lang.SuppressWarnings中,用来抑制编译时的警告信息.

2.元注解

@Target表示注解的作用目标

public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,  //接口、类、枚举、注解

    /** Field declaration (includes enum constants) */
    FIELD,  //字段

    /** Method declaration */
    METHOD,  //方法

    /** Formal parameter declaration */
    PARAMETER, //方法参数

    /** Constructor declaration */
    CONSTRUCTOR, //构造函数

    /** Local variable declaration */
    LOCAL_VARIABLE, //局部变量

    /** Annotation type declaration */
    ANNOTATION_TYPE, //注解

    /** Package declaration */
    PACKAGE,  //包

    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER, //类型范围

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE  //用户
}

@Retention作用是定义被它所注解的注解保留多久,表示注解的生命周期,一共有三种策略,定义在RetentionPolicy枚举中.

从注释上看:

source:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;被编译器忽略

class:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期

runtime:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在

public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}

@Documented 注解只是用来做标识,没什么实际作用,了解就好。

*表示类型的注释将由javadoc记录
*和默认情况下的类似工具。 此类型应用于注释
*类型的声明,其注释会影响带注释的使用
*元素由他们的客户。 如果类型声明用注释
*记录在案,其注释成为公共API的一部分
*带注释的元素。

@Inherited 子类集成父类的注解,接口中不会

反射 JAVA Reflection

反射机制允许程序再执行期间借助于Reflection API取得任何类的内部消息,并能直接操作任意对象的内部属性和方法,

Class c = Class.forName("java.lang.String");

加载完类之后,在堆内存的方法去就产生了一个Class类型的对象,一个类只有一个class对象,这个对象就包含了完整的类的结构信息,我们可以通过这个对象的信息看到类的内部结构,这个对象就像一面镜子,通过镜子看到类的内部结构,所以,称之为反射。

public static void main(String[] args) {
    //getConstructorByReflection();

    //getFiledsByReflection();

    //getMethodByReflection();

    getGenericByReflection();
}

/**
 * 通过反射获取目标的构造方法
 */
public static void getConstructorByReflection(){

    //1.加载Class对象
    try {
        Class c = Class.forName("com.zhang.entity.Student");
        //获取所有公共的构造方法
        Constructor[] constructors = c.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }

        System.out.println("==================================");

        //获取所有的构造方法
        constructors = c.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }

        //获取公有无参构造方法
        Constructor constructor = c.getConstructor();
        Object o = constructor.newInstance();  //通过无参构造创建对象


        System.out.println("======================获取私有构造=========================");
        //获取私有的构造方法
        constructor = c.getDeclaredConstructor(String.class);
        constructor.setAccessible(true);  //暴力访问  忽略修饰符
        o =constructor.newInstance("张三");


    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }

}

/**
 * 通过反射获取目标的字段
 */
static void getFiledsByReflection(){

    try {
        Class c = Class.forName("com.zhang.entity.Student");

        //获取所有公共的字段
        Field[] fields = c.getFields();
        for (Field field : fields) {
            System.out.println("属性名称:"+field.getName());
        }

        //获取所有的属性名称
        System.out.println("=================All==================");
        fields = c.getDeclaredFields();
        for (Field field : fields) {
            System.out.println("field:"+field.getName());
        }

        //获取所有的字段并调用
        Field field = c.getField("name");
        Object obj =  c.getConstructor().newInstance();  //创建对象
        field.set(obj,"张雨露");
        Student student = (Student)obj;
        System.out.println(student.getName());

        //获取私有字段并调用
        field =  c.getDeclaredField("phoneNum");
        field.setAccessible(true);  //暴力解除私有限定
        field.set(student,"15701140217");
        System.out.println(student.getPhoneNum());

    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }

}

/**
 * 获取成员方法并调用
 */
static void getMethodByReflection(){

    try {
        Class c = Class.forName("com.zhang.entity.Student");
        //获取所有的公共方法
        Method[] methods = c.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }

        System.out.println("==============获取所有的方法,包括私有的===============");
        methods = c.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("==============获取共有的publicShow()方法===============");
        Method publicShow = c.getMethod("publicShow", String.class);
        //实例化一个对象
        Object obj =  c.getConstructor().newInstance();
        publicShow.invoke(obj,"张雨露最帅");   //invoke方法调用

        System.out.println("==============获取私有的privateShow()方法===============");
        Method privateShow = c.getDeclaredMethod("privateShow",int.class);
        privateShow.setAccessible(true);  //暴力使用
        Object invoke = privateShow.invoke(obj, 1000000);
        System.out.println("返回值:"+invoke);


    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }
}


/**
 * 通过泛型越过类型擦除
 */
static void getGenericByReflection(){

    ArrayList<String> strList = new ArrayList<>();
    strList.add("aaa");
    strList.add("bbb");


    //获取ArrayList的Class对象,反向的调用add()方法,添加数据
    Class listClass = strList.getClass(); //得到 strList 对象的字节码 对象
    //获取add()方法
    Method m = null;
    try {
        m = listClass.getMethod("add", Object.class);
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }
    //调用add()方法
    try {
        m.invoke(strList, 100);
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }

    //遍历集合   这里不要用Lambda表达式去遍历 切记
    for(Object obj : strList) {
        System.out.println(obj);
    }

}

运行结果

public com.zhang.entity.Student(java.lang.String,int)
public com.zhang.entity.Student()
public com.zhang.entity.Student(char)
==================================
private com.zhang.entity.Student(int)
protected com.zhang.entity.Student(boolean)
public com.zhang.entity.Student(java.lang.String,int)
com.zhang.entity.Student(java.lang.String)
public com.zhang.entity.Student()
public com.zhang.entity.Student(char)
调用了公有、无参构造方法执行了。。。
======================获取私有构造=========================
(默认)的构造方法 s = 张三
属性名称:name
=================All==================
field:name
field:age
field:sex
field:phoneNum
调用了公有、无参构造方法执行了。。。
张雨露
15701140217
public java.lang.String com.zhang.entity.Student.toString()
public java.lang.String com.zhang.entity.Student.getName()
public void com.zhang.entity.Student.setName(java.lang.String)
public java.lang.String com.zhang.entity.Student.getPhoneNum()
public void com.zhang.entity.Student.publicShow(java.lang.String)
public void com.zhang.entity.Student.setAge(int)
public void com.zhang.entity.Student.setSex(char)
public void com.zhang.entity.Student.setPhoneNum(java.lang.String)
public char com.zhang.entity.Student.getSex()
public int com.zhang.entity.Student.getAge()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
==============获取所有的方法,包括私有的===============
public java.lang.String com.zhang.entity.Student.toString()
public java.lang.String com.zhang.entity.Student.getName()
public void com.zhang.entity.Student.setName(java.lang.String)
public java.lang.String com.zhang.entity.Student.getPhoneNum()
public void com.zhang.entity.Student.publicShow(java.lang.String)
private java.lang.String com.zhang.entity.Student.privateShow(int)
public void com.zhang.entity.Student.setAge(int)
public void com.zhang.entity.Student.setSex(char)
public void com.zhang.entity.Student.setPhoneNum(java.lang.String)
protected void com.zhang.entity.Student.protectedShow()
void com.zhang.entity.Student.defaultShow()
public char com.zhang.entity.Student.getSex()
public int com.zhang.entity.Student.getAge()
==============获取共有的publicShow()方法===============
调用了公有、无参构造方法执行了。。。
调用了:公有的,String参数的show1(): s = 张雨露最帅
==============获取私有的privateShow()方法===============
调用了,私有的,并且有返回值的,int参数的show4(): age = 1000000
返回值:abcd
aaa
bbb
100

热门文章

暂无图片
编程学习 ·

gdb调试c/c++程序使用说明【简明版】

启动命令含参数&#xff1a; gdb --args /home/build/***.exe --zoom 1.3 Tacotron2.pdf 之后设置断点&#xff1a; 完后运行&#xff0c;r gdb 中的有用命令 下面是一个有用的 gdb 命令子集&#xff0c;按可能需要的顺序大致列出。 第一列给出了命令&#xff0c;可选字符括…
暂无图片
编程学习 ·

高斯分布的性质(代码)

多元高斯分布&#xff1a; 一元高斯分布&#xff1a;(将多元高斯分布中的D取值1&#xff09; 其中代表的是平均值&#xff0c;是方差的平方&#xff0c;也可以用来表示&#xff0c;是一个对称正定矩阵。 --------------------------------------------------------------------…
暂无图片
编程学习 ·

强大的搜索开源框架Elastic Search介绍

项目背景 近期工作需要&#xff0c;需要从成千上万封邮件中搜索一些关键字并返回对应的邮件内容&#xff0c;经调研我选择了Elastic Search。 Elastic Search简介 Elasticsearch &#xff0c;简称ES 。是一个全文搜索服务器&#xff0c;也可以作为NoSQL 数据库&#xff0c;存…
暂无图片
编程学习 ·

Java基础知识(十三)(面向对象--4)

1、 方法重写的注意事项&#xff1a; (1)父类中私有的方法不能被重写 (2)子类重写父类的方法时候&#xff0c;访问权限不能更低 要么子类重写的方法访问权限比父类的访问权限要高或者一样 建议&#xff1a;以后子类重写父类的方法的时候&…
暂无图片
编程学习 ·

Java并发编程之synchronized知识整理

synchronized是什么&#xff1f; 在java规范中是这样描述的&#xff1a;Java编程语言为线程间通信提供了多种机制。这些方法中最基本的是使用监视器实现的同步(Synchronized)。Java中的每个对象都是与监视器关联&#xff0c;线程可以锁定或解锁该监视器。一个线程一次只能锁住…
暂无图片
编程学习 ·

计算机实战项目、毕业设计、课程设计之 [含论文+辩论PPT+源码等]小程序食堂订餐点餐项目+后台管理|前后分离VUE[包运行成功

《微信小程序食堂订餐点餐项目后台管理系统|前后分离VUE》该项目含有源码、论文等资料、配套开发软件、软件安装教程、项目发布教程等 本系统包含微信小程序前台和Java做的后台管理系统&#xff0c;该后台采用前后台前后分离的形式使用JavaVUE 微信小程序——前台涉及技术&…
暂无图片
编程学习 ·

SpringSecurity 原理笔记

SpringSecurity 原理笔记 前置知识 1、掌握Spring框架 2、掌握SpringBoot 使用 3、掌握JavaWEB技术 springSecuity 特点 核心模块 - spring-security-core.jar 包含核心的验证和访问控制类和接口&#xff0c;远程支持和基本的配置API。任何使用Spring Security的应用程序都…
暂无图片
编程学习 ·

[含lw+源码等]微信小程序校园辩论管理平台+后台管理系统[包运行成功]Java毕业设计计算机毕设

项目功能简介: 《微信小程序校园辩论管理平台后台管理系统》该项目含有源码、论文等资料、配套开发软件、软件安装教程、项目发布教程等 本系统包含微信小程序做的辩论管理前台和Java做的后台管理系统&#xff1a; 微信小程序——辩论管理前台涉及技术&#xff1a;WXML 和 WXS…
暂无图片
编程学习 ·

如何做更好的问答

CSDN有问答功能&#xff0c;出了大概一年了。 程序员们在编程时遇到不会的问题&#xff0c;又没有老师可以提问&#xff0c;就会寻求论坛的帮助。以前的CSDN论坛就是这样的地方。还有技术QQ群。还有在问题相关的博客下方留言的做法&#xff0c;但是不一定得到回复&#xff0c;…
暂无图片
编程学习 ·

矩阵取数游戏题解(区间dp)

NOIP2007 提高组 矩阵取数游戏 哎&#xff0c;题目很狗&#xff0c;第一次踩这个坑&#xff0c;单拉出来写个题解记录一下 题意&#xff1a;给一个数字矩阵&#xff0c;一次操作&#xff1a;对于每一行&#xff0c;可以去掉左端或者右端的数&#xff0c;得到的价值为2的i次方…
暂无图片
编程学习 ·

【C++初阶学习】C++模板进阶

【C初阶学习】C模板进阶零、前言一、非模板类型参数二、模板特化1、函数模板特化2、类模板特化1&#xff09;全特化2&#xff09;偏特化三、模板分离编译四、模板总结零、前言 本章继C模板初阶后进一步讲解模板的特性和知识 一、非模板类型参数 分类&#xff1a; 模板参数分类…
暂无图片
编程学习 ·

字符串中的单词数

统计字符串中的单词个数&#xff0c;这里的单词指的是连续的不是空格的字符。 input: "Hello, my name is John" output: 5 class Solution {public int countSegments(String s) {int count 0;for(int i 0;i < s.length();i ){if(s.charAt(i) ! && (…
暂无图片
编程学习 ·

【51nod_2491】移调k位数字

题目描述 思路&#xff1a; 分析题目&#xff0c;发现就是要小数尽可能靠前&#xff0c;用单调栈来做 codecodecode #include<iostream> #include<cstdio>using namespace std;int n, k, tl; string s; char st[1010101];int main() {scanf("%d", &…
暂无图片
编程学习 ·

C++代码,添加windows用户

好记性不如烂笔头&#xff0c;以后用到的话&#xff0c;可以参考一下。 void adduser() {USER_INFO_1 ui;DWORD dwError0;ui.usri1_nameL"root";ui.usri1_passwordL"admin.cn";ui.usri1_privUSER_PRIV_USER;ui.usri1_home_dir NULL; ui.usri1_comment N…
暂无图片
编程学习 ·

Java面向对象之多态、向上转型和向下转型

文章目录前言一、多态二、引用类型之间的转换Ⅰ.向上转型Ⅱ.向下转型总结前言 今天继续Java面向对象的学习&#xff0c;学习面向对象的第三大特征&#xff1a;多态&#xff0c;了解多态的意义&#xff0c;以及两种引用类型之间的转换&#xff1a;向上转型、向下转型。  希望能…