Java:注解、Lambda 表达式、Servlet
·
一、Java 注解(Annotation)
注解是代码中的元数据(描述数据的数据),不直接影响代码逻辑,但可在编译、类加载、运行时被工具或框架解析,实现特定功能。
1. 注解的核心作用
- 提供元信息:标记代码特性(如
@Override标记方法重写) - 编译检查:辅助编译器发现错误(如
@Deprecated标记废弃元素) - 运行时处理:供框架动态获取信息(如 Spring 的
@Component实现 Bean 扫描) - 简化配置:替代传统 XML 配置(如 MyBatis 的
@Select标记 SQL 语句)
2. 常见内置注解
| 注解名称 | 作用 | 应用场景 |
|---|---|---|
@Override |
标记方法重写父类 / 接口的方法 | 避免重写方法名拼写错误 |
@Deprecated |
标记类 / 方法 / 字段已废弃 | 提示开发者使用替代方案 |
@SuppressWarnings |
抑制编译器警告(如未使用变量警告) | 消除不必要的编译提示 |
@FunctionalInterface |
标记接口为函数式接口(仅一个抽象方法) | 确保 Lambda 表达式可使用 |
3. 自定义注解(重点)
需用 @interface 声明,且通常搭配元注解(描述注解的注解)使用,控制自定义注解的保留范围、应用目标等。
(1)常用元注解
| 元注解名称 | 作用 | 可选值 |
|---|---|---|
@Retention |
定义注解的保留阶段 | SOURCE(源码)、CLASS(字节码)、RUNTIME(运行时) |
@Target |
定义注解可应用的目标(类 / 方法 / 字段等) | TYPE(类)、METHOD(方法)、FIELD(字段)等 |
@Inherited |
允许子类继承父类的注解 | 无参数 |
(2)自定义注解代码示例
import java.lang.annotation.*;
// 元注解:保留到运行时(可通过反射获取),仅能应用于方法
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
// 注解元素(类似方法,可指定默认值)
String value() default "默认描述"; // 无参数名时,使用时可省略"value="
int version() default 1;
}
// 使用自定义注解
public class AnnotationDemo {
// 应用注解,指定value和version
@MyAnnotation(value = "测试方法", version = 2)
public void testMethod() {
System.out.println("执行测试方法");
}
public static void main(String[] args) throws NoSuchMethodException {
// 通过反射获取方法上的注解(需@Retention为RUNTIME)
Class<AnnotationDemo> clazz = AnnotationDemo.class;
var method = clazz.getMethod("testMethod");
// 判断方法是否有MyAnnotation注解
if (method.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
// 获取注解元素值
System.out.println("注解描述:" + annotation.value());
System.out.println("注解版本:" + annotation.version());
}
}
}
输出结果:
注解描述:测试方法
注解版本:2
二、Lambda 表达式
Lambda 是 Java 8 引入的函数式编程语法,用于简化 “单抽象方法接口”(函数式接口)的实例创建,核心是 “简化代码,聚焦逻辑”。
1. 核心前提:函数式接口
- 定义:仅包含一个抽象方法的接口(可含默认方法、静态方法)
- 标记:建议用
@FunctionalInterface注解,强制编译器检查接口是否符合函数式接口规范 - 示例:
Runnable(void run())、Comparator(int compare(T o1, T o2))
2. Lambda 语法格式
Lambda 表达式本质是 “接口抽象方法的匿名实现”,语法格式:
(参数列表) -> { 方法体 }
- 简化规则:
- 参数列表:若只有一个参数,可省略括号;参数类型可省略(编译器自动推断)
- 方法体:若只有一行代码,可省略大括号和
return(若有返回值)
3. 常见使用场景(代码示例)
(1)结合 Runnable 接口(线程创建)
// 传统方式:匿名内部类
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("传统线程执行");
}
}).start();
// Lambda 方式(简化)
new Thread(() -> System.out.println("Lambda线程执行")).start();
(2)结合 Comparator 接口(集合排序)
import java.util.Arrays;
import java.util.Comparator;
public class LambdaDemo {
public static void main(String[] args) {
String[] arr = {"apple", "banana", "cherry"};
// 传统方式:匿名内部类(按字符串长度排序)
Arrays.sort(arr, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
});
// Lambda 方式(简化,按字符串长度排序)
Arrays.sort(arr, (s1, s2) -> s1.length() - s2.length());
// 输出排序结果
System.out.println(Arrays.toString(arr)); // [apple, banana, cherry]
}
}
(3)自定义函数式接口
// 自定义函数式接口(仅一个抽象方法)
@FunctionalInterface
interface Calculator {
int calculate(int a, int b);
}
public class CustomLambda {
public static void main(String[] args) {
// Lambda 实现加法逻辑
Calculator add = (a, b) -> a + b;
System.out.println("3+5=" + add.calculate(3, 5)); // 3+5=8
// Lambda 实现乘法逻辑
Calculator multiply = (a, b) -> a * b;
System.out.println("4*6=" + multiply.calculate(4, 6)); // 4*6=24
}
}
三、Servlet
Servlet 是运行在服务器端的 Java 程序,用于处理客户端(浏览器)的 HTTP 请求,生成动态 Web 内容,是 Java Web 开发的核心组件。
1. Servlet 核心体系
Servlet 基于接口实现,核心类 / 接口关系如下:
Servlet(顶层接口) → GenericServlet(通用实现,适配非HTTP协议) → HttpServlet(HTTP协议专用实现)
- 实际开发中,通常继承
HttpServlet(而非直接实现Servlet接口),因为它封装了 HTTP 请求的处理逻辑(如 GET/POST 请求)。
2. Servlet 生命周期(重点)
Servlet 由 Web 服务器(如 Tomcat)管理,生命周期分为 5 个阶段:
- 加载与实例化:服务器启动或首次接收请求时,加载 Servlet 类并创建实例(仅一次)
- 初始化:调用
init(ServletConfig config)方法,初始化配置(仅一次,可获取初始化参数) - 请求处理:每次接收客户端请求,调用
service(HttpServletRequest req, HttpServletResponse resp)方法(核心阶段,多次执行)service方法会自动根据请求方式(GET/POST)调用对应的doGet或doPost方法
- 销毁:服务器关闭或 Servlet 被移除时,调用
destroy()方法(仅一次,用于释放资源,如关闭数据库连接) - 卸载:实例被垃圾回收器回收
3. 开发 Servlet 的核心步骤(代码示例)
(1)创建 Servlet 类(继承 HttpServlet)
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
// 注解配置:指定Servlet的访问路径(替代web.xml配置)
@WebServlet("/HelloServlet")
public class HelloServlet extends HttpServlet {
// 处理GET请求(客户端通过URL直接访问或表单method="get")
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置响应内容类型(解决中文乱码)
resp.setContentType("text/html;charset=UTF-8");
// 获取响应输出流,向客户端输出内容
PrintWriter out = resp.getWriter();
out.write("<h1>Hello, Servlet!</h1>");
out.write("<p>这是我的第一个Servlet程序</p>");
out.close();
}
// 处理POST请求(表单method="post")
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 解决POST请求中文乱码
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
// 获取表单参数(假设表单有name="username"的输入框)
String username = req.getParameter("username");
PrintWriter out = resp.getWriter();
out.write("<h1>欢迎你," + username + "!</h1>");
out.close();
}
}
(2)配置与访问
- 配置方式:
- 注解配置(推荐,Java EE 6+):用
@WebServlet("/HelloServlet")指定访问路径(如/HelloServlet) - XML 配置(传统方式):在
web/WEB-INF/web.xml中配置 Servlet 映射
- 注解配置(推荐,Java EE 6+):用
- 访问方式:
启动 Tomcat 服务器后,通过 URL 访问:http://localhost:8080/项目名/HelloServlet- 若发送 GET 请求,会执行
doGet方法;若通过表单发送 POST 请求,会执行doPost方法
- 若发送 GET 请求,会执行
4. 核心 API(HttpServletRequest 与 HttpServletResponse)
| API 类别 | 核心作用 | 常用方法 |
|---|---|---|
HttpServletRequest |
封装客户端请求信息(如参数、请求头、Cookie) | getParameter(String name)(获取请求参数)、getSession()(获取 Session) |
HttpServletResponse |
封装服务器响应信息(如响应内容、响应头、Cookie) | setContentType(String type)(设置响应类型)、getWriter()(获取输出流)、sendRedirect(String url)(重定向) |
总结
- 注解:元数据标记,自定义注解需搭配元注解(
@Retention/@Target),运行时注解需通过反射解析 - Lambda 表达式:简化函数式接口实例创建,核心是 “(参数) -> 方法体”,需依赖函数式接口(仅一个抽象方法)
- Servlet:服务器端组件,继承
HttpServlet处理 HTTP 请求,生命周期由 Tomcat 管理,核心是doGet/doPost方法处理请求
更多推荐
所有评论(0)