1.官方定义:
定义: (1)Java 注解用于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。Java 注解是从 Java5 开始添加到 Java 的。
(2)用一个词就可以描述注解,那就是元数据,即一种描述数据的数据。所以,可以说注解就是源代码的元数据。
(3)注解是一种能被添加到java代码中的元数据,类、方法、变量、参数和包都可以用注解来修饰。注解对于它所修饰的代码并没有直接的影响。
2.非官方定义: 注解就是一枚徽章,可以标识类一种身份
二.注解的分类:
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