注解小结

1.定义

注解:
Java语言中的类、方法、变量、参数和包等都可以被标注。和Javadoc不同,Java标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java虚拟机可以保留标注内容,在运行时可以获取到标注内容。 当然它也支持自定义Java标注
JDK1.5之后的特征
用于说明程序
一般在框架中使用
格式:
@AnnotationName

2.预定义注解

@Override:
重写/实现方法的情况下,检查方法声明是否和父类或者接口中的方法声明一致。强制格式检查。

@Deprecated
标注当前方法已过时,例如 Data日期类内的一些方法

@SuppressWarnings(“all”)
压制警告,可以用于一些代码中存在明确无异常的情况下,压制一些警告

3.自定义注解

3.1 格式

格式:
public @interface AnnotationName {
属性列表;
}

Annotation注解是可以编译得到对应的.class字节码文件,验证了注解是可以参与编译过程的

通过反编译工具可以得到一下内容
【Annotation本质】
public interface MyAnnotation1 extends java.lang.annotation.Annotation {
}

MyAnnotation1
本质是一个interface,同时java.lang.annotation.Annotation 子接口

public @interface MyAnnotation1 {
    // 属性 ==> 方法形式
}

3.2 Annotation注解属性

属性:
开发书写代码使用注解的方式中,数据使用方式更加偏向于属性概念。
使用
1. 在书写代码中使用
@MyAnnotation(id=1, name=“骚磊”, age=16)
2. 利用反射时,会涉及到getXXX方法
通过属性名获取对应值的概念来完成的

【但是实际上是利用abstract方法来完成属性概念的】

属性使用的格式[实际按照方法格式操作]
1. 属性的值数据类型和对应具体数据 ==> 返回值类型和返回的数据
属性类型支持:
a. 基本数据类型
b. String类型
c. 其他的注解类型
d. 枚举类型
枚举就是一个带有名字的常量,为了更好的域阅读性和操作
e. 以上类型对相应的数组

	属性值要求
		a. 定义属性时可以使用default关键字,加上默认值,该属性在使用的过程中是
		没有强制要求属性值,如果没有赋予属性值,采用对应的默认值操作,如果赋
		值,使用对应值
		
		b. 如果注解中有且只有一个value属性,或者说注解中除value属性之外,都有
		默认值,不管是类,方法,成员变量,包使用当前注解是可以直接在括号内加入
		对应数据类型数值、
		
		c. 如果属性是数组类型, {}大括号保存,并且不同的内容,使用,隔开
2. 属性的键名字 ==> 方法的名字

案例

package com.qfedu.a_annotation.checkMethod;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 测试Tools类内的方法,如果方法带有Check注解,执行测试,记录异常
 *
 * @author Anonymous
 */
@ClassAnnotation(className = "com.qfedu.a_annotation.checkMethod.Utils")
public class TestProject {
    public static void main(String[] args)
            throws IOException, InvocationTargetException,
            IllegalAccessException, ClassNotFoundException, NoSuchMethodException, InstantiationException {

        // 从注解中获取对应的属性
        Class<TestProject> cls  = TestProject.class;
        ClassAnnotation annotation = cls.getAnnotation(ClassAnnotation.class);
        String s = annotation.className();
        Class<?> aClass = Class.forName(s);

        Object tools = aClass.getConstructor().newInstance();
        // 获取所有Tools类内的方法,不包括父类方法
        Method[] declaredMethods = aClass.getDeclaredMethods();

        // 出现错误的次数
        int count = 0;
        long l = System.currentTimeMillis();
        BufferedWriter br = new BufferedWriter(new FileWriter("./src/log.txt"));

        // 遍历方法数组
        for (Method declaredMethod : declaredMethods) {
            declaredMethod.setAccessible(true);

            // 判断当前方法是否带有注解@Check,标记
            if (declaredMethod.isAnnotationPresent(Check.class)) {
                try {
                    // 执行方法
                    declaredMethod.invoke(tools);
                } catch (Exception e) {
                    count += 1;

                    // 1. 哪一个方法出现异常
                    br.write("方法:" + declaredMethod.getName());
                    br.newLine();
                    // 2. 发生什么异常 获取原因,获取对应的类型
                    br.write("异常类型:" + e.getCause().getClass().getSimpleName());
                    br.newLine();
                    // 3. 异常信息
                    br.write("异常信息:" + e.getCause().getMessage());
                    br.newLine();
                    br.write("-----------------------------------------------------------------");
                    br.newLine();
                }
            }
        }

        long l1 = System.currentTimeMillis();
        br.write("出现错误的次数:" + count);
        br.newLine();
        br.write("总耗时:" + (l1 - l));
        br.newLine();

        br.close();
    }
}

此时的Util

package com.qfedu.a_annotation.checkMethod;

/**
 * @author Anonymous
 * @description
 * @date 2020/3/10 16:49
 */
public class Utils {
    @Check
    public void test() {
        throw new IndexOutOfBoundsException("下标越界");
    }
}

执行流程:

1.从注解中获取对应属性 此时的属性是 Util类
2.加载这个类
3.利用反射从目前的这个类里 提取出成员变量以及成员方法。
4.循环遍历此时的方法 看是否有@check标记,如果有标记 那么执行 发现错误的话 计数器加一

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`@RequestMapping`是Spring MVC框架中的一个重要注解,用于将HTTP请求映射到控制器的方法上。这个注解用于简化RESTful风格的Web服务开发,使得路由和处理逻辑更加清晰和模块化。下面是一些关于`@RequestMapping`实验小结的关键点: 1. **路径映射**:`@RequestMapping`用于指定一个或多个HTTP请求方法(GET, POST, PUT, DELETE等),以及对应的URL路径。例如,`@RequestMapping(value = "/users", method = RequestMethod.GET)`表示该方法处理所有发送到"/users"路径的GET请求。 2. **请求参数**:可以通过`@RequestParam`或`@PathVariable`注解处理请求参数,如查询参数、路径变量等。如`@RequestParam(name="id") Long userId`会从请求中获取名为"id"的查询参数。 3. **返回类型**:`@ResponseBody`可以用来标记返回值为JSON或XML响应体,而`@ModelAttribute`用于处理表单提交的模型属性。 4. **异常处理**:可以使用`@ExceptionHandler`注解来捕获特定的异常,并提供定制的错误处理。 5. **分组和扫描器**:为了方便管理,可以通过`@RequestMapping`的`@ControllerAdvice`或`@Controller`的`@RequestMapping(basePath = "/api/v1")`来对多个控制器进行分组或定义统一的路径前缀。 相关问题-- 1. `@RequestMapping`如何处理不同类型的HTTP请求? 2. 如何在Spring MVC中使用`@RequestParam`和`@PathVariable`? 3. `@ResponseBody`和`@ModelAttribute`的区别是什么? 4. 如何在Spring MVC中实现全局异常处理? 5. 分组和扫描器在Spring MVC中的应用场景是什么?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值