首页 > 其他 > 详细

注解的认识

时间:2020-01-02 16:53:02      阅读:90      评论:0      收藏:0      [点我收藏+]

.注解的定义

1.官方定义:

定义: (1)Java 注解用于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。Java 注解是从 Java5 开始添加到 Java 的。

(2)用一个词就可以描述注解,那就是元数据,即一种描述数据的数据。所以,可以说注解就是源代码的元数据。

(3)注解是一种能被添加到java代码中的元数据,类、方法、变量、参数和包都可以用注解来修饰。注解对于它所修饰的代码并没有直接的影响。

2.非官方定义: 注解就是一枚徽章,可以标识类一种身份

.注解的分类:

1.java中自带的注解: @overrride  表示当前方法覆盖了父类的方法,即就是方法的重写. @Deprecated表示方法已经过时,方法上有横线,使用时会有警告。@SuppresWarnings 表示关闭一些警告信息(通知java编译器忽略特定的编译警告)

2.自定义的注解

(1).定义注解的属性: 访问修饰符必须为public,不写默认为public;该元素的类型只能是基本数据类型、String、Class、枚举类型、注解类型以及上述类型的一位数组;default代表默认值,值必须和定义的数据类型一致;如果没有默认值,代表后续使用注解时必须给该类型元素赋值;该元素的名称一般定义为名词,如果注解中只有一个元素,请把名字起为value;()不是定义方法参数的地方,也不能在括号中定义任何参数,仅仅只是一个特殊的语法;使用的时候操作元素类型像在操作属性,解析的时候操作元素类型像在操作方法。

2.注解的获取: 注解没有反射就是注释;注解的获取完全依靠于一套反射的API

3.元注解: 

(1)@Target :

注解的作用域,用于说明注解的使用范围(如方法,接口,对象...)

ElemenetType.CONSTRUCTOR--------构造器声明

ElemenetType.FIELD ------------------域声明(包括 enum 实例)

ElemenetType.LOCAL_VARIABLE----- 局部变量声明

ElemenetType.METHOD --------------方法声明

ElemenetType.PACKAGE----------包声明

ElemenetType.PARAMETER ----------参数声明

ElemenetType.TYPE------- 类,接口(包括注解类型)或enum声明   

(2)@Retention:

描述的注解在什么范围内有效。

RetentionPolicy.SOURCE-------只在源码显示,编译时会丢失

RetentionPolicy.CLASS-----编译时会记录到class中,运行时忽略

RetentionPolicy.RUNTIME------运行时存在,可以通过反射读取   

(3)@Inherited

是一个标记注解,没有成员,表示允许子类继承该注解,也就是说如果一个使用了@Inherited修饰的注解被用于一个class时,则这个注解将被该class的子类继承拥有

使用了@Inherited修饰的注解只能被子类所继承,并不可以从它所实现的接口继承

子类继承父类的注解时,并不能从它所重载的方法继承注解

(4)@Documented是一个标记注解,没有成员。用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。

(5)@Repeatable

用于声明标记的注解为可重复类型注解,可以在同一个地方多次使用

(6)@Navite

声明属性是可以被native代码所引用的

.注解的案例

1.配置文件

松耦合:XML

紧耦合:注解

Spring2.5以上都是基于注解的

Hibernate3.x以后是基于注解的

2. Hibernate根据Pojo对象生成建表语句

代码如下:

import java.io.FileFilter;

import java.io.IOException;

import java.net.JarURLConnection;

import java.net.URL;

import java.util.ArrayList;

import java.util.Enumeration;

import java.util.List;

import java.util.jar.JarEntry;

import java.util.jar.JarFile;

/*

 * 一个工具类,获取指定包下的所有文件

 */

public class PackageScannerUtil {

    /**

     * 给我一个包名,获取该包下的所有class文件

     * @param packageName 包名 com.xxx.xxx

     * @param isRecursive 是否递归

     * @return 返回class文件的集合

     * @throws ClassNotFoundException

     */

    public static List<Class<?>> getClassList(String packageName, boolean isRecursive) throws ClassNotFoundException {

 

        //声明一个返回List

        List<Class<?>> classList = new ArrayList<>();

        //将对应的包名转换为路径

        try {

            //Enumeration枚举接口,当中有两个方法,一个是判断是否有下一个元素,还有一个是取到下一个元素

            Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(packageName.replace(‘.‘, ‘/‘));

            while (urls.hasMoreElements()) {

                URL url = urls.nextElement();

                //System.out.println(url); // file:/D:/SXTJava/annotation/bin/annotation

                if (url != null) {

                    //拿到文件的协议

                    String protocol = url.getProtocol();

                    //如果是file

                    if ("file".equals(protocol)) {

                        //取到文件的路径

                        String packagePath = url.getPath();// /D:/SXTJava/annotation/bin/annotation

                        addClass(classList, packagePath, packageName, isRecursive);

                    } else if ("jar".equals(protocol)) { //如果是jar包的情况:此情况没有测试

                        JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();

                        JarFile jarFile = jarURLConnection.getJarFile(); //取到jar包下的文件

                        Enumeration<JarEntry> jarEntries = jarFile.entries();

                        while (jarEntries.hasMoreElements()) { //遍历jarEnyries

                            JarEntry jarEntry = jarEntries.nextElement();//取到元素

                            String jarEntryName = jarEntry.getName(); //取到文件名

                            if (jarEntryName.endsWith(".class")) { //如果文件名以.class结尾,将对应的文件添加至集合中

                                String name = jarEntryName.substring(0, jarEntryName.lastIndexOf("."));

                                System.out.println(name);

                                String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replaceAll("/", ".");//取到类名

                                if (isRecursive || className.substring(0, className.lastIndexOf(".")).equals(packageName)) {

                                    classList.add(Class.forName(className));

                                }

                            }

                        }

                    }

                }

            }

        } catch (IOException e) {

            e.printStackTrace();

        }

        return classList;

    }

    /**

     * 将对应包名下的所有.class文件加入到classList集合中

     * @param classList   存放classList文件的集合

     * @param packagePath 包路径

     * @param packageName 包名

     * @param isRecursive 是否递归

     * @throws ClassNotFoundException

     */

    private static void addClass(List<Class<?>> classList, String packagePath, String packageName,

                                 boolean isRecursive) throws ClassNotFoundException {

        //取到路径下所有的对应的文件,包括.class文件和目录

        File[] files = getClassFiles(packagePath);

        if (files != null) {  //如果files不为空的话,对它进行迭代

            for (File file : files) {

                //取到文件名

                String fileName = file.getName(); //Column.class

                if (file.isFile()) {//如果取到的是文件

                    //取到对应的类名,这里的类名是权限定名

                    String className = getClassName(packageName, fileName);

                    classList.add(Class.forName(className));

                } else {

                    if (isRecursive) {

                        ///D:/SXTJava/annotation/bin/annotation+包名(fileName:test)

                        String subPackagePath = getSubPackagePath(packagePath, fileName);

                        String subPackageName = getSubPackageName(packageName, fileName);

                        //递归调用自己

                        addClass(classList, subPackagePath, subPackageName, isRecursive);

                    }

                }

            }

        }

    }

    /**

     * 获取子包

     * @param packageName

     * @param fileName

     * @return

     */

    private static String getSubPackageName(String packageName, String fileName) {

        String subPackageName = fileName;

        if (packageName != null && (!"".equals(packageName))) {

            subPackageName = packageName + "." + subPackageName;

        }

        return subPackageName;

    /**

     * 获取子目录

     *

     * @param packagePath 包的路径

     * @param fileName    文件的路径

     * @return

     */

    private static String getSubPackagePath(String packagePath, String fileName) {

        String subPackagePath = fileName;

        if (packagePath != null && (!"".equals(packagePath))) {

            subPackagePath = packagePath + "/" + subPackagePath;

        }

        return subPackagePath;

    }

    /**

     * 根据传入的包名和文件名返回对应类的全限定名

     *

     * @param packageName 包名

     * @param fileName    文件名 类名.后缀名

     * @return 包名.类名

     */

    private static String getClassName(String packageName, String fileName) {

        String className = fileName.substring(0, fileName.indexOf("."));

        if (packageName != null && !"".equals(packageName)) {

            className = packageName + "." + className;

        }

        return className;

    }

    /**

     * 获取class文件

     *

     * @param packagePath

     * @return

     */

    private static File[] getClassFiles(String packagePath) {

        //FileFilter文件过滤器

        return new File(packagePath).listFiles(new FileFilter() {

 

            @Override

            public boolean accept(File file) {

                //如果是.class文件,或者是目录就返回true

                return (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory();

            }

        });

    }

    public static void main(String[] args) throws ClassNotFoundException {

      List<Class<?>> classes = PackageScannerUtil.getClassList("com.shsxt", true);

        for (Class<?> clazz : classes) {

            System.out.println(clazz);

        }

    }

}

注解的认识

原文:https://www.cnblogs.com/ruanjianwei/p/12133399.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!