注解(Annotations)是什么?你用过哪些注解?解释依赖注入(DI)。

在编程语言中,注解(Annotation)是一种元数据机制,允许程序员向源代码中添加信息,这些信息可以被编译器、IDE或其他工具读取和处理,但不会影响程序的运行时行为。注解主要用于代码的自文档化、编译时检查、运行时处理(如依赖注入、持久化等)以及生成其他代码或XML配置文件等。

以下是一些常见的Java注解示例:

  1. @Override:表明该方法是重写父类中的某个方法,编译器会对此进行检查。

    java 复制代码
    public class ChildClass extends ParentClass {
    
        @Override
    
        public void someMethod() { ... }
    
    }
  2. @Deprecated:表示某个方法或者类已经不再推荐使用,并且可能在未来版本中被移除。

    java 复制代码
    @Deprecated
    
    public void oldMethod() { ... }
  3. @Autowired:在Spring框架中用于自动装配bean依赖关系。

    java 复制代码
    @Autowired
    
    private SomeService someService;
  4. @NotNull@NonNull(来自第三方库):表明某个参数或属性不应为null,这有助于编译时和运行时的空指针异常检测。

    java 复制代码
    public void someMethod(@NotNull String nonNullParam) { ... }
  5. JUnit测试相关的注解,例如:

    • @Test:标记一个方法为单元测试方法

    • @Before@After:分别在每个测试方法执行前和后执行的方法

    java 复制代码
    @Test
    
    public void testSomeFunctionality() { ... }
    
    
    
    @Before
    
    public void setUp() { ... }
    
    
    
    @After
    
    public void tearDown() { ... }

根据不同编程语言和框架,可用的注解类型和功能会有所不同。以上列举的是基于Java的一些常见注解示例。

依赖注入(Dependency Injection,简称 DI)是一种软件设计模式,用于减少软件组件之间的耦合度并提高它们的可测试性和可维护性。在传统的编程中,一个对象常常自行创建或查找它所依赖的对象,这导致各个组件之间紧密绑定,不利于复用和解耦。

依赖注入的核心思想是:组件不应该自行创建或查找其依赖的对象,而是应该由外部的一个"智慧"容器(例如 Spring 框架中的 IoC 容器)来负责创建和管理这些依赖对象,并将其传递给需要它们的组件。

具体实施时,依赖注入可以通过三种主要方式实现:

  1. 构造函数注入:通过构造函数向组件传递依赖对象。
java 复制代码
public class MyClass {

    private MyDependency dependency;



    public MyClass(MyDependency dependency) {

        this.dependency = dependency;

    }

}
  1. setter 注入:通过setter方法注入依赖对象。
java 复制代码
public class MyClass {

    private MyDependency dependency;



    public void setDependency(MyDependency dependency) {

        this.dependency = dependency;

    }

}



// 使用Spring配置文件示例:
  1. 接口注入:依赖对象作为接口的一部分被提供给组件。

依赖注入的优势在于它可以使组件独立于其依赖的具体实现,这样就可以轻松地更换或替换依赖,比如在单元测试中使用模拟对象代替实际对象,或者在不同环境中使用不同的实现。此外,这种设计也使得系统的架构更加清晰和模块化。

是的,Java从JDK 8开始支持默认方法(Default Methods)。默认方法是在接口中定义的具有实现的方法,并使用 default 关键字修饰。这样做的主要目的是允许接口在不破坏现有实现类的二进制兼容性的前提下进行扩展。

例如:

java 复制代码
public interface MyInterface {

    default void someMethod() {

        System.out.println("This is a default method in MyInterface.");

    }

}

然后,任何实现了这个接口的类可以选择重写这个默认方法,或者直接使用接口提供的默认实现:

java 复制代码
public class MyClass implements MyInterface {

    // 不重写someMethod时,会使用MyInterface的默认实现

    // 如果需要自定义行为,可以这样做:

    @Override

    public void someMethod() {

        System.out.println("This is a custom implementation in MyClass.");

    }

}
相关推荐
yaoxin52112314 分钟前
497. Java 反射 - 使用反射读取注解
java·开发语言·python
eralong1 小时前
Java 面向对象:继承、多态、接口
java·后端
哦虎!1 小时前
【数据库】事务
java·数据库·mysql
CDN3601 小时前
流媒体加速实践:出海东南亚短视频点播频繁缓冲,HLS 分片与 Nginx 配置调优
java·网络·nginx·流媒体加速
程序员黑豆2 小时前
Java中的null与NullPointerException完全指南:安全处理、实战排查与面试题
java·前端·ai编程
晴天162 小时前
Electron面试题-Day19
java·javascript·electron
GeekZHR3 小时前
C语言指针进阶补充6:动态内存管理、mem系列内存函数、复杂指针声明,一次补齐指针的“三大盲区“
java·c语言·算法·指针
Herbert_hwt3 小时前
第七章 Java深入理解枚举类型
java·开发语言·算法
侧耳倾听1113 小时前
java 日志框架简介
java·开发语言
她的男孩3 小时前
我用 LLM 把后台 CRUD 效率提升 10 倍:AI 代码生成器的架构与落地实践
java·后端·架构