1 注解
1.1注解的理解
-
- 注解(Annotation)也被称为元数据(Metadata),用于修饰解释 包、类、方法、属性、构造器、局部变量等数据信息。
-
- 和注释一样,注解不影响程序逻辑,但注解可以被编译或运行,相当于嵌入在代码中的补充信息。
-
- 在 JavaSE 中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在 JavaEE 中注解占据了更重要的角
色,例如用来配置应用程序的任何切面,代替 java EE 旧版中所遗留的繁冗代码和 XML 配置等。
- 在 JavaSE 中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在 JavaEE 中注解占据了更重要的角
1.2基本的 Annotation 介绍
使用 Annotation 时要在其前面增加 @ 符号, 并把该 Annotation 当成一个修饰符使用。用于修饰它支持的程序元
素
三个基本的 Annotation:
-
- @Override: 限定某个方法,是重写父类方法, 该注解只能用于方法-
-
- @Deprecated: 用于表示某个程序元素(类, 方法等)已过时
-
- @SuppressWarnings: 抑制编译器警告
1.3基本的 Annotation 应用案例
1.3.1 Override实例
java
package javaannotation;
public class OverrideDemo1 {
public static void main(String[] args) {
}
}
class Father{
public void fly(){
System.out.println("Father fly......");
}
public void say(){};
}
class Son extends Father{
//1. @Override 注解放在 fly 方法上,表示子类的 fly 方法时重写了父类的 fly
//2. 这里如果没有写 @Override 还是重写了父类 fly
//3. 如果你写了@Override 注解,编译器就会去检查该方法是否真的重写了父类的
// 方法,如果的确重写了,则编译通过,如果没有构成重写,则编译错误
//4. 看看 @Override 的定义
@Override
public void fly() {
super.fly();
}
@Override
public void say() {
super.say();
}
}
1.3.2 SuppressWarnings实例
1. 当我们不希望看到这些警告的时候,可以使用 SuppressWarnings 注解来抑制警告信息
2. 在{""} 中,可以写入你希望抑制(不显示)警告信息
3. 可以指定的警告类型有
all,抑制所有警告
boxing,抑制与封装/拆装作业相关的警告
cast,抑制与强制转型作业相关的警告
dep-ann,抑制与淘汰注释相关的警告
deprecation,抑制与淘汰的相关警告
fallthrough,抑制与 switch 陈述式中遗漏 break 相关的警告
finally,抑制与未传回 finally 区块相关的警告
hiding,抑制与隐藏变数的区域变数相关的警告
incomplete-switch,抑制与 switch 陈述式(enum case)中遗漏项目相关的警告
javadoc,抑制与 javadoc 相关的警告
nls,抑制与非 nls 字串文字相关的警告
null,抑制与空值分析相关的警告
rawtypes,抑制与使用 raw 类型相关的警告
resource,抑制与使用 Closeable 类型的资源相关的警告
restriction,抑制与使用不建议或禁止参照相关的警告
serial,抑制与可序列化的类别遗漏 serialVersionUID 栏位相关的警告
static-access,抑制与静态存取不正确相关的警告
static-method,抑制与可能宣告为 static 的方法相关的警告
super,抑制与置换方法相关但不含 super 呼叫的警告
synthetic-access,抑制与内部类别的存取未最佳化相关的警告
sync-override,抑制因为置换同步方法而遗漏同步化的警告
unchecked,抑制与未检查的作业相关的警告
unqualified-field-access,抑制与栏位存取不合格相关的警告
unused,抑制与未用的程式码及停用的程式码相关的警告
4. 关于 SuppressWarnings 作用范围是和你放置的位置相关
java
package javaannotation;
import java.util.ArrayList;
import java.util.List;
@SuppressWarnings({"all"})
public class SuppressWarningDemo {
public static void main(String[] args) {
List list=new ArrayList<>();
list.add("jack");
list.add("tom");
list.add("mary");
int i;
System.out.println(list.get(1));
}
}
1.4 自定义注解
public @interface 注解名称{
public 属性类型 属性名() default 默认值
}
java
package javaannotation;
//自定义注解
public @interface MyAnnotation {
//在注解中只能定义属性 public 属性类型 属性名() default 默认值
/*
属性类型必须是以下范围之一
1.8种基本数据类型
2.String类型
3.Class类型
4.枚举类型
5.注解类型
6.以上所有的类型的一维数组形式
* */
public String name();
public double price() default 99.0;
}
@MyAnnotation(name = "测试") //没有指定price属性,默认为99
public class TestAnnotaion {
@MyAnnotation(name="数据",price = 123)
private String name;
@MyAnnotation(name="构造方法")
public TestAnnotaion(){
}
@MyAnnotation(name = "成员方法",price = 100)
public void method(@MyAnnotation(name="参数") String msg){
}
}
1.5元注解
元注解:就是修饰注解的注解
常见的元注解有两个
- @Target:约束自定义注解只能在哪些地方使用
- @Retention:声明注解的生命周期
Target中可以使用的值定义在ElementType枚举类中,常用的值如下 :
TYPE,类,接口
FIELD,成员变量
METHOD,成员方法
PARAMETER,方法参数
CONSTRUCTOR,构造器
LOCAL_VARIABLE,局部变量
java
package javaannotation.demo;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Book2 {
public String value();
public double price() default 99.0;
public String[] author(); //有多个作者
}
Retention中可以使用的值定义在RetentionPolicy枚举类中,常用的值如下 :
SOURCE:注解只作用在源码阶段,生成的字节码文件中不存在
RUNTIME:注解作用在源码阶段,字节码文件阶段,运行阶段(开发常用)
CLASS:注解作用在源码阶段,字节码文件阶段,运行阶段不存在,默认值
1.6注解解析
注解的解析
- 注解操作中经常需要进行解析,注解析解析就是判断是不否存在注解,存在注解就解析出内容
与注解解析相关的接口
- AnnotatedElement:该接口定义了与注解解析相关的解析方法
Annotation[] getDeclaredAnnotations():获得当前对象上的所有注解,返回注解数组
T getDecaredAnnotation(Class)annotationClass):根据注解类型获得注解对象
boolean isAnnotationPresent(ClassannotationClass)判断当前对象是否使用了指定的注解,如果是的话返回true,否则返回false
代码演示
java
package javaannotation.demo2;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Book {
public String value();
}
package javaannotation.demo2;
public class BookStore {
@Book("Java入门") //注解析特殊作用:把value的值赋给当前成员变量
private String bookName;//成员变量
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
}
package javaannotation.demo2;
import org.junit.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class BookStroeTest {
@Test
public void testParse() throws NoSuchFieldException, InstantiationException, IllegalAccessException {
//1.获取Class对象
Class<BookStore> bookStoreClass=BookStore.class;
BookStore bookStore = bookStoreClass.newInstance();
//获取成员变量对象
Field field=bookStoreClass.getDeclaredField("bookName");
//私有成员变量
field.setAccessible(true);
//判断:成员变量上是否有BOOK注解
if (field.isAnnotationPresent(Book.class)) {
//有注解
Book book=field.getDeclaredAnnotation(Book.class);
//获取BOOK注解中的值
String bookName=book.value();
//使用反射技术给私有成员变量赋值
field.set(bookStore,bookName);
}
System.out.println(bookStore.getBookName());
}
}
1.7注解解析(扩展)
java
package javaannotation.demo5.init;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//注解类
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface CreateObject {
public String value();
}
package javaannotation.demo5.dao;
import javaannotation.demo5.pojo.User;
import java.util.ArrayList;
import java.util.List;
//dao 层
public class UserDao {
public List<User> findAllUser(){
List<User> users=new ArrayList<>();
users.add(new User(1,"熊大",23));
users.add(new User(2,"熊二",23));
users.add(new User(3,"张三",23));
return users;
}
//添加
public boolean addUser(){
return true;
}
//删除
public boolean deleteUser(){
return true;
}
}
package javaannotation.demo5.service;
import javaannotation.demo5.dao.UserDao;
import javaannotation.demo5.init.CreateObject;
import javaannotation.demo5.pojo.User;
import java.net.PortUnreachableException;
import java.util.List;
//service层
public class UserService {
//成员变量(需要依赖userDao对象)
@CreateObject("userDao")
private UserDao userDao;
public List<User> queryAllUser(){
return userDao.findAllUser();
}
public boolean addUser(User user){
return false;
}
public boolean deleteUser(int id){
return false;
}
}
package javaannotation.demo5.init;
import javaannotation.demo5.dao.UserDao;
import javaannotation.demo5.service.UserService;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class App {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//项目程序启动,就会初始化一些对象和参数
//获取到UserService的Class对象
Class<UserService> userServiceClass=UserService.class;
//构造器
Constructor<UserService> cons=userServiceClass.getConstructor();
//成员变量
Field[] fields = userServiceClass.getDeclaredFields();
for (Field field:fields){
//判断,成员变量是否有@CreateObject注妥
if (field.isAnnotationPresent(CreateObject.class)) {
//有注分则解析
CreateObject obj=field.getDeclaredAnnotation(CreateObject.class);
String objectValue=obj.value();
if(objectValue.equals("userDao")){
UserDao userDao = new UserDao();
field.setAccessible(true);
field.set(cons.newInstance(),userDao);
}
}
}
}
}