Java_语言特性_高级功能

1 注解

        注解是在在代码中添加的额外信息,这些信息独立于业务逻辑,能在编译期、类加载期或运行时读取利用,用于实现编译期检查、代码标记与框架配置、运行时处理等特定功能,提升代码可读性与可维护性.分为注解和类型注解.
 

1.1 分类

       ①SOURCE 注解:仅存在于源代码中,编译时被丢弃,如@Component.

        ②CLASS 注解:编译时记录到 class 文件,但运行时 JVM 不保留.常用于编译期处理,如生成辅助代码等.

        ③RUNTIME 注解:运行时保留,可通过反射获取,如 @Component.

1.2 元注解

        元注解用于注解其他注解,规定被注解注解的特性.

(1) @Retention:决定注解的生命周期,即注解在什么阶段存在.

        RetentionPolicy.SOURCE:仅存在于源代码中,编译时被丢弃.

        RetentionPolicy.CLASS:编译时记录到 class 文件,但运行时 JVM 不保留.

        RetentionPolicy.RUNTIME:运行时保留,可通过反射获取.

(2) @Target:指定注解可以应用的目标元素类型.

        ElementType.TYPE:可应用于类、接口、枚举类型.

        ElementType.FIELD:用于字段.

        ElementType.METHOD:用于方法.

        ElementType.PARAMETER:应用于方法参数.

        ElementType.CONSTRUCTOR:用于构造函数.

        ElementType.LOCAL_VARIABLE:用于局部变量.

        ElementType.ANNOTATION_TYPE:用于注解类型本身,即可以注解其他注解.

        ElementType.PACKAGE:用于包声明

        ElementType.TYPE_USE:表示注解可应用于任何使用类型的地方,如对象创建、类型转换、泛型参数等场景.

        ElementType.TYPE_PARAMETER:表示可应用于类型参数,如泛型类型参数.

(3) @Documented:表示使用该注解的元素应该被包含在 Javadoc 文档中,方便其他开发者了解该元素的特殊属性或用途.

(4) @Inherited:标记的注解具有继承性,子类会自动继承该注解,但仅对类注解有效,对于类的方法、字段等元素上的注解不具备继承性.

1.3 自定义注解

        使用 @interface 关键字定义自定义注解,可包含成员变量,使用时需为成员变量赋值(除非有默认值).

// 定义
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.METHOD)
public @interface MyAnnotation {
    String value() default "";
    int count() default 0;
}

// 使用
public class MyClass {
    @MyAnnotation(value = "example", count = 10)
    public void myMethod() {
        // 方法实现
    }
}

1.4 常用注解

1.4.1 常用注解

        (1) @overwrite:用于明确子类方法重写父类方法.编译器会检查其方法签名,若与父类不匹配则抛出编译错误,以此确保方法重写的正确性.

class Shape {
    public void draw() {
        System.out.println("Drawing a shape");
    }
}

class Circle extends Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a circle");
    }
}

        (2) Deprecated:标记不建议使用的代码元素(类、方法、字段等).使用被标记元素时编译器会警告,提示其可能在未来版本移除,为代码升级维护提供指引,避免使用废弃功能.

public class MathUtils {
    @Deprecated
    public static int addOld(int a, int b) {
        return a + b;
    }

    public static int add(int a, int b) {
        return Integer.sum(a, b);
    }
}

        (3) @Nullable 和 @NonNull:@Nullable 注解表示被注解的变量、参数或返回值在运行时可能为 null,@NonNull 注解则表示被注解的元素在运行时不会为 null.用于静态分析工具在编译期检测空指针异常,大大提高代码的健壮性.

import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.nullness.qual.NonNull;

public class NullabilityExample {
    public void printLength(@NonNull String str) {
        System.out.println(str.length());
    }

    public @Nullable String getNullableString() {
        return null;
    }
}

1.4.2 Spring 框架中的常用注解

        ①@Component:标记类为 Spring 容器组件,容器会自动扫描并实例化该类,实现依赖注入和控制反转.是@Service、@Repository和@Controller注解的通用形式.

import org.springframework.stereotype.Component;

@Component
public class UserService {
    // 业务逻辑代码
}

        ②@Controller:用于标记控制层的类,负责接收前端传来的请求,调用业务逻辑层的服务进行处理,并将处理结果返回给前端.

        ③@Service:用于标记业务逻辑层的类,负责接收控制层的请求,调用数据访问层的服务进行处理,并将处理结果返回控制层.

        ④@Repository:用于标记数据访问层的类,用于处理数据库相关的操作,还能将数据库操作中的异常抛给上层应用来处理.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.List;

// 标记为 Spring Boot 应用的主类
@SpringBootApplication
public class SpringAnnotationsExample implements CommandLineRunner {

    @Autowired
    private UserService userService;

    public static void main(String[] args) {
        SpringApplication.run(SpringAnnotationsExample.class, args);
    }

    // 服务启动后做初始化
    @Override
    public void run(String... args) throws Exception {
        // 调用服务层方法添加用户
        userService.addUser(new User("John Doe"));
        System.out.println("User added successfully.");
    }
}

// 定义用户实体类
class User {
    private String name;

    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

// 数据访问层,处理数据库操作
@Repository
class UserRepository {
    private List users = new ArrayList<>();

    public void save(User user) {
        users.add(user);
    }

    public List findAll() {
        return users;
    }
}

// 业务逻辑层,调用数据访问层方法
@Service
class UserService {
    @Autowired
    private UserRepository userRepository;

    public void addUser(User user) {
        userRepository.save(user);
    }

    public List getAllUsers() {
        return userRepository.findAll();
    }
}

// 控制器层,处理 HTTP 请求
@Controller
class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/users")
    @ResponseBody
    public List getUsers() {
        return userService.getAllUsers();
    }
}
    

1.4.3 JUnit 测试框架中的常用注解

        ①@Test:标记测试方法,在测试时执行,用于验证代码的逻辑.

        ②@Before:标记的方法在测试方法前执行,用于初始化测试环境、准备数据.

        ③@After:标记的方法在测试方法后执行,用于清理测试环境(如关闭连接、释放资源).

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import static org.junit.Assert.assertEquals;

public class DatabaseTest {
    private Connection connection;

    @Before
    public void setUp() throws SQLException {
        connection = DriverManager.getConnection("jdbc:sqlite:test.db");
    }

    @Test
    public void testDatabaseOperation() throws SQLException {
        // 数据库操作测试逻辑
        assertEquals(1, 1);
    }

    @After
    public void tearDown() throws SQLException {
        if (connection!= null) {
            connection.close();
        }
    }
}

你可能感兴趣的:(编程语言,java)