注解
什么是注解?
是元数据(Annotation) ,是一种对代码进行说明的数据,JDK1.5引入的新规范,是与类、接口、枚举等引用类型处于同一个层次,可以用在包、类、属性、方法、方法的参数和局部变量等的前边,不影响代码的语义,可以对其进行解析
注解Annotation: 是一种引用数据类型(在类加载的时候会生成字节码文件)
注解在以后的用途:
注解的作用:
注解只能起到一个标识的作用
spring框架:基于注解的开发模式
学习了反射可以不使用new关键字去创建一个类的实例
spring是一个容器里面会存放很多类的实例
我怎么知道有哪些类需要去创建实例,那些类不需要创建实例?
用注解去标识一下,需要创建实例的类,用注解去做一个标识
在spring框架检测到该类有注解时,就会通过反射机制去创建该类的实例
beans: User、Student、Person、Animal
创建一个注解
public @interface MyAnnotation {
}
注解中可以拥有属性,但是不能拥有方法
如果你给一个注解声明了属性,那么在注解修饰元素的时候,就必须要给属性赋值,除非你在声明属性的时候,给了属性默认值
在注解中声明属性
public @interface MyAnnotation {
//在注解中如何去声明属性
String name() default "";
int i();
String[] strings() default {"1","2"};
//枚举类型
Math math() default Math.Max;
Math[] maths() default {Math.Max,Math.Count,Math.Sum};
}
在注解中定义属性只能时八大基本数据类型、字符串类型String、枚举类型、以及主要类型所对应的数组类型
在定义属性时,如果属性名称是value,那在注解修饰元素,并且给属性赋值的时候,属性名称可以省略不写
@MyAnnotation(name = "123",i = 100)
注解运用范围
注解使用时的语法格式是:
@注解类型名
注解可以出现在类上、属性上、方法上、变量上等
注解可以出现在注解类型上
JDK内置注解
Deprecated 用 @Deprecated
注释的程序元素,不鼓励程序员使用这样的元素,通过是因为它很危险或存在更好的选择
Override表示一个方法声明打算重写超类中的另一个方法声明
SuppressWarnings
指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告
元注解
什么是元注解?
用来标注“注解类型”的“注解”,称为元注解
修饰注解的注解
在定义注解时需要通过元注解指定例如注解的使用场合、是否生成文档、是否可以继承、注解保持的策略(是否能被反射机制所获取到)
元注解:
@Target({ElementType.METHOD,ElementType.TYPE})
表示注解的作用域
参数只能是枚举类型数组
//使得注解能标识在类和属性前
@Target({ElementType.TYPE,ElementType.FIELD})
public @interface MyAnnotation {
}
@Retention(RetentionPolicy.RUNTIME)
注解的生命周期
RetentionPolicy(设置注解的生命周期以及保持性策略)
: SOURCE:
当前注解只保留在源码这个层面上,在类加载的时候不会去生成字节码文件,而且不可以被反射机制所获取!
CLASS:
在类加载的时候会生成字节码文件,但是不可以被发射机制获取
RUNTIME:
在类加载的时候可以生成字节码文件,而且可以被反射机制获取工
@Inherited
标识允许子注解来继承这个注解(注意这里只能是继承不能是接口上使用,而且只能继承类上的注解,不能继承方法上的注解)
@Documented
生成JAVADOC时会包含注解
如何通过反射机制获取注解:
1、创建类对应的字节码对象
2、通过字节码对象获取注解字节码对象
public class Annotation01 {
public static void main(String[] args) {
try {
//创建字节码对象
Class aClass = Class.forName("com.os467.pojo.User");
//获取类上的注解
MyAnnotation annotation = (MyAnnotation)aClass.getAnnotation(MyAnnotation.class);
if (annotation != null){
//获取注解上的属性
System.out.println(annotation.name());
//获取属性字节码对象
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
MyAnnotation annotation1 = declaredField.getAnnotation(MyAnnotation.class);
if (annotation1 != null){
System.out.println(declaredField.getName()+" 这个属性上有注解");
}
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
根据注解自动生成SQL查询语句
package com.os467;
import com.os467.Annotion.Table;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
public class ORM {
private ORM(){
}
public static String getSql(Object obj){
StringBuilder stringBuilder = new StringBuilder();
//获取obj字节码对象
Class aClass = obj.getClass();
Table annotation = (Table)aClass.getAnnotation(Table.class);
//表的名称
String table = null;
if (annotation != null){
//获取表的名称
table = annotation.value();
stringBuilder.append("select * from "+ table +" where ");
}
//获取属性字节码对象
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
//打破封装
declaredField.setAccessible(true);
com.os467.Annotion.Field annotation1 = declaredField.getAnnotation(com.os467.Annotion.Field.class);
//注解不为空的情况下拼接
if (annotation1 != null){
try {
//获取属性值
Object o = declaredField.get(obj);
//检查email属性是否有多个","隔开
if (o != null && o.toString().contains(",")){
stringBuilder.append(annotation1.value() + " in(" + o + ") and");
}else if (o != null && !o.toString().equals("0")){
stringBuilder.append(annotation1.value() + " = ");
if (o instanceof String){
stringBuilder.append("'" + o + "'" + " and ");
}
if (o instanceof Integer){
stringBuilder.append(o + " and ");
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
String s = stringBuilder.toString();
//替换掉最后的and
s = s.substring(0,s.length() - 4);
if (s.contains("=")){
return s;
}
return null;
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以邮件至 1300452403@qq.com