注解
注解(Annotation),也叫元数据。一种代码级别的说明。
它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。
它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
格式:
@interface 注解名{}
作用:
编译检查
替代配置文件
定义注解(元注解:注解上的注解)
分析代码(用到反射)
java中3个常见的注解(理解)
自定义注解(理解)
注解属性:
注解本质就是一个接口, 可以用javap 这个命令反编译一下 注解的字节码文件 例如 javap myan.class
那接口中可以有常量和抽象方法
抽象方法在注解中就称之为注解属性
@Override:声明该方法是从分类上继承过来的,执行编译期的检查
@SuppressWarnings:抑制警告 值有好多,只需要知道一个 all 抑制所有的警告
@Deprecated:声明 该方法不赞成使用
自定义注解(理解)
注解属性:
注解本质就是一个接口, 可以用javap 这个命令反编译一下 注解的字节码文件 例如 javap myan.class
那接口中可以有常量和抽象方法
抽象方法在注解中就称之为注解属性
例如: public @interface MyAnnotation {
//注解本质上是一个接口,那接口中的抽象方法,其实就是注解中的属性
public abstract String name(); //注解的属性,前面的public abstract 可以省略
int hehe(); //前面的数据类型,不是所有类型都支持
Class haha();
}
注解属性支持的类型如下:
基本类型
String
Class
Annotation
Enum:枚举
以上类型对应的一维数组
注意:
一旦注解有属性了,使用注解的时候必须赋值,(除非这个注解属性有默认值)
public @interface MyAnnotation { int hehe(); //注意我这个注解有属性了
}
那么我在另一个类上添加我自定义的注解就会报错,因为我注解中的属性没有赋值
@MyAnnotation() //报错 要不报错括号里面要赋值,除非有默认值
public class Test {
}
下面就是正确的
@MyAnnotation(hehe=100) //给注解中属性赋值,就不报错了
public class Test {
}
注解中有多个属性,在给属性赋值时,用逗号隔开
public @interface MyAnnotation { int hehe(); //注意我这个注解有属性了
String haha();
int[] num();
}
//多个属性赋值
@MyAnnotation(hehe=100,haha='abc',num={10,20}) //给注解中属性赋值,就不报错了
public class Test {
}
赋值的格式:
@注解名(属性名=属性值)
若注解类型为数组,且只有一个值的时候,可以有两种写法
方式1:
属性名 = { 值 }
方式2:
属性名=属性值
注意特殊情况若属性名为value的时候,且只需要为这个value属性赋值的时候,value可以省略
public @interface MyAnnotation {
String value(); //这个属性名叫value 比较特殊
}
注解中的属性名为value时,赋值时可以省略value
@MyAnnotation("zhangsan") //属性名为value时可以省略value
//@MyAnnotation(value="zhangsan") 当然不省略也可以
public class Test {
}
我们可以通过default 关健字给属性赋上默认值
public @interface MyAnnotation { int num() default 100;
String name() default "zhangsan";
}
@MyAnnotation() //因为注解的属性中有默认值,我们可以不用赋值
public class Test {
}
使用注解:就是注解可以加在哪里,我们可以通过元注解,来标识我们自己定义的注解可以加在什么位置
元注解:(理解)
定义在注解上的注解
@Retention 规定注解保留到什么阶段 值为RetentionPolicy的三个枚举值
SOURCE:只在代码中保留,在字节码文件中就删除了
CLASS:在代码和字节码文件中保留
RUNTIME:所有阶段都保留
@Target 规定注解作用在什么上面 值为ElementType的枚举值
TYPE:作用在类 接口 等上面
METHOD:作用方法上面
FIELD:作用字段上面
我们可以在Java文档中查看 Retention 和 Target
例如:
@Target(ElementType.METHOD) //这个表示我们自定义的注解只能加在方法上
@Retention(RetentionPolicy.RUNTIME) //表示我们的注解保留到运行阶段
@interface MyAnnotation { int num() default 100;
String name() default "zhangsan";
}
使用注解
public class Test {
@MyAnnotation() 这个注解只能加在方法上
public void add(){
}
}
### 案例扩展:
获取连接的工具类,通过配置四个参数
步骤分析:
1.自定义一个注解JDBCInfo
添加元注解:
在程序运行的时候使用 @Retention
只能作用在方法上 @Target
添加注解属性
String driverClass() default “com.mysql.jdbc.Driver”;
String url();
String username() default “root”;
String password();
2.在jdbcutils工具类中提供一个getConnection,在方法上面添加一个注解 @JDBCInfo(…)
getConnection方法需要进行的操作:获取注解上的四个属性值
获取字节码文件
获取该方法上的注解
获取注解的值
3.运行的时候可以通过getConnection获取一个连接
例子
注解类:定义连接数据库所需的四个参数
@Target(ElementType.METHOD) //这个表示我们自定义的注解只能加在方法上
@Retention(RetentionPolicy.RUNTIME) //表示我们的注解保留到运行阶段
public @interface JDBCAnnotation {
String driverClass() default "com.mysql.jdbc.Driver";
String url() default "jdbc:mysql://localhost:3306/hbm";
String user() default "root";
String password() default "123456";
}
工具类
public class JDBCUtils {
@JDBCAnnotation(password = "123456")
public static Connection getConnection() throws NoSuchMethodException, ClassNotFoundException, SQLException {
//获取该类的字节码文件对象
Class clazz= JDBCUtils.class;
//获取方法对象
Method m = clazz.getMethod("getConnection");
//判断该方法上是否有注解,如果有获取到注解
boolean b = m.isAnnotationPresent(JDBCAnnotation.class);//参数:是注解的Class类型
if(b){ //如果方法上有注解,获取注解,并拿到注解的属性值
JDBCAnnotation annotation = m.getAnnotation(JDBCAnnotation.class);
//获取注解属性的值
String driverClass = annotation.driverClass();
String url = annotation.url();
String user = annotation.user();
String password = annotation.password();
Class.forName(driverClass);
return DriverManager.getConnection(url,user,password);
}return null;
}}
测试类
public class Test {
public static void main(String[] args) throws NoSuchMethodException, SQLException, ClassNotFoundException {
Connection connection = JDBCUtils.getConnection();
System.out.println(connection);
}
}
servlet3.0
3.0支持注解开发,没有web.xml这个文件了
内嵌了文件上传功能
/
例如:
创建servlet
在Servlet类上面添加 @WebServlet(urlPatterns="/demo2")
一个Servlet 也可以配置多个映射路径,访问哪一个都行 urlPatterns这个注解属性是个数组,所以可以配置多个值
@WebServlet(urlPatterns={ "/demo2", "/demo21" },loadOnStartup=2)
@WebServlet(name = "ServletDemo1",urlPatterns = {"/demo1","/demo2","/demo3"},initParams = {@WebInitParam(name = "num",value = "100")},loadOnStartup = 0)
825

被折叠的 条评论
为什么被折叠?



