constructor

news2024/10/8 23:00:30

java 构造函数

在Java中,构造函数是用于初始化对象的特殊方法。构造函数具有与类同名的方法,并且没有返回类型。以下是Java构造函数的一些关键点和示例:

特点:

  1. 名称与类名相同:构造函数的名称必须与类的名称完全一致。
  2. 没有返回类型:构造函数不返回任何类型,包括void
  3. 自动调用:当创建类的对象时,构造函数被自动调用。
  4. 可以重载:可以在一个类中定义多个构造函数,每个构造函数具有不同的参数列表。
  5. 默认构造函数:如果没有定义任何构造函数,Java编译器会提供一个默认的无参构造函数。

构造函数的类型:

  1. 无参构造函数:没有参数的构造函数。
  2. 有参构造函数:含有参数的构造函数,用于初始化对象时传递不同的值。

示例代码:

class Car {
    String model;
    int year;

    // 无参构造函数
    Car() {
        this.model = "Default Model";
        this.year = 0;
    }

    // 有参构造函数
    Car(String model, int year) {
        this.model = model;
        this.year = year;
    }

    void displayInfo() {
        System.out.println("Model: " + model + ", Year: " + year);
    }
}

public class Main {
    public static void main(String[] args) {
        // 使用无参构造函数
        Car car1 = new Car();
        car1.displayInfo();

        // 使用有参构造函数
        Car car2 = new Car("test", 0000);
        car2.displayInfo();
    }
}

执行结果:

Model: Default Model, Year: 0
Model: test, Year: 0000

在这个例子中,我们定义了一个Car类,有两个构造函数。第一个是无参构造函数,默认赋值给modelyear。第二个是有参构造函数,允许在创建对象时指定modelyear的值。

springboot 构造函数

在Spring Boot和Spring框架中,构造函数通常用于依赖注入。Spring通过构造函数将所需的依赖项注入到类中。在Spring应用程序中,使用构造函数注入可以确保类的依赖项在对象创建时就被完全初始化。

构造函数注入的优点:

  1. 不可变性:通过构造函数注入,依赖项在对象创建后就是不可变的。
  2. 可测试性:容易进行单元测试,因为依赖项可以通过构造函数的参数传递。
  3. 完成初始化:在对象创建时就可以保证其依赖项的完整性。

如何在Spring Boot中使用构造函数注入:

以下是一个简单的例子,演示了如何在Spring Boot中使用构造函数注入1 2

示例代码:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    private final UserRepository userRepository;

    // 构造函数注入
    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public User getUserById(Long id) {
        return userRepository.findById(id).orElse(null);
    }
}

在上面的代码中,我们有一个UserService类,该类依赖于UserRepository。通过使用构造函数注入,我们确保在UserService实例化时,userRepository已经被注入。如果@Autowired不想用(因为在Spring 4.3以后,如果只存在一个构造函数的话,@Autowired是可以省略的)。

配合Spring Boot应用:

下面是一个更完整的Spring Boot应用示例:

Application.java - 主应用程序入口
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
UserRepository.java - 模拟的仓库接口
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
User.java - 实体类(假设有一个User实体)
import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class User {
    @Id
    private Long id;
    private String name;

    // Getters and setters
    // ...
}

这个例子演示了如何通过构造函数注入将UserRepository注入到UserService中,以便在服务类中可以使用该仓库进行数据库操作。这样做使得代码更清晰、可维护,还便利了测试过程。

springboot 有参构造

在Spring Boot中,有参构造函数通常用作显式的依赖注入方式之一,通过构造函数将所需的依赖项注入到类中。Spring会自动识别构造函数,并使用上下文中定义的bean来满足依赖关系。

有参构造函数注入

有参构造函数注入是一种依赖注入的方式,其中通过构造函数传递所需的依赖项。在Spring 4.3及更高版本中,如果类只有一个构造函数,Spring会自动使用该构造函数进行注入,无需显式添加@Autowired注解。

示例代码

以下示例展示了如何在Spring Boot中使用有参构造函数进行依赖注入:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

// 一个示例服务类
@Service
public class OrderService {

    private final PaymentService paymentService;
    private final NotificationService notificationService;

    // 使用有参构造函数进行依赖注入
    @Autowired
    public OrderService(PaymentService paymentService, NotificationService notificationService) {
        this.paymentService = paymentService;
        this.notificationService = notificationService;
    }

    public void placeOrder(Order order) {
        // 处理支付
        paymentService.processPayment(order.getAmount());

        // 发送通知
        notificationService.notifyUser(order.getUser());

        // 订单处理逻辑
        System.out.println("Order placed successfully!");
    }
}
支持的依赖类

假设还有相应的PaymentServiceNotificationService类:

import org.springframework.stereotype.Service;

// 支付服务
@Service
public class PaymentService {
    public void processPayment(double amount) {
        System.out.println("Processed payment of $" + amount);
    }
}

// 通知服务
@Service
public class NotificationService {
    public void notifyUser(String user) {
        System.out.println("Notification sent to user: " + user);
    }
}
主应用程序入口
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

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

说明

  1. OrderService 使用了两个服务:PaymentServiceNotificationService,它们通过构造函数参数传递进行注入。
  2. 自动装配:构造函数注入是通过@Autowired进行的,不过在Spring 4.3之后,如果类只有一个构造函数,可以省略@Autowired
  3. 无循环依赖:构造函数注入避免了循环依赖问题,确保在实例化时所有依赖项都已经准备就绪。

这样设计能够确保代码的清晰性和模块化,同时也保持了服务组件的独立性和测试的便利性。

springboot 无参构造

在Spring Boot中,使用无参构造函数的情况一般出现在需要用默认值初始化对象或当类中没有复杂的依赖关系时。在很多情况下,Spring自身会使用无参构造函数来初始化bean,特别是当没有声明任何构造函数时,Java会提供一个默认的无参构造函数。

使用无参构造函数的场景

无参构造函数通常用于简单的POJO(Plain Old Java Objects)或DTO(Data Transfer Objects),它们不需要Spring进行管理的复杂依赖注入。

示例代码

下面是一个简单的示例,演示如何在Spring Boot中使用无参构造函数:

import org.springframework.stereotype.Service;

@Service
public class SimpleService {

    private String message;

    // 无参构造函数
    public SimpleService() {
        this.message = "Default Message";
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public void showMessage() {
        System.out.println("Message: " + message);
    }
}

在这个示例中,SimpleService类拥有一个无参构造函数,用于初始化message字段为默认值。

POJO或DTO类示例

通常,无参构造函数也用于数据传输对象:

public class UserDTO {

    private Long id;
    private String name;
    private String email;

    // 无参构造函数
    public UserDTO() {
    }

    public UserDTO(Long id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }

    // Getters and setters
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
}

说明

  1. 默认构造:当类中没有其他构造函数时,Java会自动提供一个无参构造函数。
  2. Spring使用:在Spring中,若未明定义构造函数或使用默认无参构造函数,Spring可以通过反射创建bean实例。
  3. 不参与依赖注入:无参构造函数不涉及依赖注入,适用于简单的对象实例化。

这种简单的无参构造在Spring Boot项目中适用于那些不需要复杂初始化的类,例如只包含数据的DTO类或简单的服务类。这有助于保持代码的简单性和清晰性。

@RequiredArgsConstructor

@RequiredArgsConstructor 是 Lombok 提供的一个注解,用于自动生成类的构造函数。这个构造函数会包含所有被 final 修饰的字段以及带有 @NonNull 注解的字段。使用这个注解可以减少样板代码,尤其是在需要依赖注入的场景中。

使用场景

在Spring Boot中,@RequiredArgsConstructor 常用于服务类中,通过构造函数注入依赖项。它可以自动生成一个包含所有 final 字段的构造函数,这些字段通常是需要注入的依赖。

示例代码

以下是一个使用 @RequiredArgsConstructor 的示例:

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class OrderService {

    private final PaymentService paymentService;
    private final NotificationService notificationService;

    public void placeOrder(Order order) {
        // 处理支付
        paymentService.processPayment(order.getAmount());

        // 发送通知
        notificationService.notifyUser(order.getUser());

        // 订单处理逻辑
        System.out.println("Order placed successfully!");
    }
}

说明

  1. 自动生成构造函数@RequiredArgsConstructor 会自动生成一个构造函数,该构造函数包含所有 final 字段。在这个例子中,paymentServicenotificationServicefinal 字段,因此它们会被包含在构造函数中。

  2. 依赖注入:在Spring中,@RequiredArgsConstructor 常用于构造函数注入。Spring会自动识别生成的构造函数,并使用上下文中的bean来满足这些依赖。

  3. 减少样板代码:使用 @RequiredArgsConstructor 可以减少手动编写构造函数的样板代码,使代码更简洁。

使用Lombok的注意事项

  • IDE支持:确保你的IDE(如IntelliJ IDEA或Eclipse)安装了Lombok插件,以便正确识别和处理Lombok注解。
  • 编译器配置:在项目的构建工具(如Maven或Gradle)中配置Lombok依赖,以确保在构建时正确处理Lombok注解。

通过使用 @RequiredArgsConstructor,开发者可以更专注于业务逻辑,而不必担心构造函数的编写和维护。

不使用@RequiredArgsConstructor

如果不使用 @RequiredArgsConstructor,你需要手动编写构造函数来实现依赖注入。手动编写构造函数虽然稍显繁琐,但可以让你对构造函数的行为有更明确的控制。

手动编写构造函数示例

以下是一个不使用 @RequiredArgsConstructor 的示例,展示如何手动编写构造函数来进行依赖注入:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class OrderService {

    private final PaymentService paymentService;
    private final NotificationService notificationService;

    // 手动编写的构造函数
    @Autowired
    public OrderService(PaymentService paymentService, NotificationService notificationService) {
        this.paymentService = paymentService;
        this.notificationService = notificationService;
    }

    public void placeOrder(Order order) {
        // 处理支付
        paymentService.processPayment(order.getAmount());

        // 发送通知
        notificationService.notifyUser(order.getUser());

        // 订单处理逻辑
        System.out.println("Order placed successfully!");
    }
}

说明

  1. 构造函数注入:通过手动编写构造函数,将 PaymentServiceNotificationService 作为参数传入,并使用 @Autowired 注解进行依赖注入。

  2. final 关键字paymentServicenotificationService 被声明为 final,确保它们在对象创建后不可变。

  3. @Autowired 注解:虽然在Spring 4.3及更高版本中,如果类只有一个构造函数,可以省略 @Autowired,但显式使用 @Autowired 可以提高代码的可读性。

手动编写构造函数的优点

  • 明确性:手动编写构造函数可以让代码更明确,特别是在需要对构造函数进行特殊处理时。
  • 灵活性:可以在构造函数中添加额外的逻辑,如参数验证或初始化操作。

手动编写构造函数虽然增加了一些样板代码,但在某些情况下(如需要自定义逻辑或不使用Lombok时)是必要的。通过这种方式,你可以完全控制对象的初始化过程。

参考:


  1. 为什么Spring不推荐使用@Autowired进行字段注 ↩︎

  2. @Autowired @Resource ↩︎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2197411.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么是数据编织

What Is Data Fabric? 【dataCamp】 What Is Data Fabric? Data fabric is a unified data architecture that connects disparate data sources, simplifying access and management while ensuring consistency and security across the entire data landscape. Data Fa…

cs61b学习 part3

如果你有许多list&#xff0c;这里将会是大量的时间&#xff0c;我指的是对于单向链表查找时间复杂度O(N)相对于数组O(1)的时间复杂度会慢一些 所以这究竟是顺序表的编写还是链表的改进? IntList public class IntList {public int first;public IntList rest;public IntLis…

webGL进阶(二)物体运动

效果&#xff1a; 模拟时钟效果。 代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewpo…

LSTM变种模型

一、GRU 1.概念 GRU&#xff08;门控循环单元&#xff0c;Gated Recurrent Unit&#xff09;是一种循环神经网络&#xff08;RNN&#xff09;的变体&#xff0c;旨在解决标准 RNN 在处理长期依赖关系时遇到的梯度消失问题。GRU 通过引入门控机制简化了 LSTM&#xff08;长短期…

Python爬虫使用实例-jsyks

目标地址&#xff1a; https://www.jsyks.com/kmy-mnks例如&#xff1a; urlhttps://www.jsyks.com/kmy-mnks # kmy-mnks 科目一-模拟考试 urlhttps://www.jsyks.com/kms-mnks # kms-mnks 科目四-模拟考试一、获取资源 先从本题分析里面得到解析答案【通过div.Exam ul li里面…

面向对象技术——设计模式

目录 层次结构 具体设计模式分类 创建型模式&#xff08;处理创建对象&#xff09; 结构型模式&#xff08;处理类和对象的组合&#xff09; 行为型模式&#xff08;描述类或者对象的交互行为&#xff09; 创建型设计模式 ​编辑 结构型设计模式 行为型设计模式​编辑 …

时序论文17|ICML24 SAMformer:华为新奇视角讨论Transformer时序预测时的收敛优化问题

论文标题&#xff1a;SAMformer: Unlocking the Potential of Transformers in Time Series Forecasting with Sharpness-Aware Minimization and Channel-Wise Attention 论文链接&#xff1a;https://arxiv.org/abs/2402.10198 代码链接&#xff1a;https://github.com/rom…

从零开始:在 VMware ESXi 环境中安装 Rocky Linux 的秘诀

哈喽大家好&#xff0c;欢迎来到虚拟化时代君&#xff08;XNHCYL&#xff09;。 “ 大家好&#xff0c;我是虚拟化时代君&#xff0c;一位潜心于互联网的技术宅男。这里每天为你分享各种你感兴趣的技术、教程、软件、资源、福利…&#xff08;每天更新不间断&#xff0c;福利…

appium中的uiautomatorviewer显示的界面为横屏解决方法

uiautomatorviewer显示的界面为横屏解决方法 解决方法&#xff1a; 修改模拟器的分辨率&#xff0c;比如540:900就可解决了

MySQL基础教程(一):连接数据库和使用表

这个专栏用来讲解 MySQL 数据的基本语法和用法。本教程的目的是方便查询 MySQL 的用法&#xff0c;因此对于原理的讲解会偏少一些&#xff0c;但特点就是会有很多实验操作图。 本专栏使用的源材料是《MySQL必知必会》这本书的源代码。 文章目录 1. 连接 MySQL 数据库2. 创建数…

搭建个人博客--1、前端页面

采用bootstrap前端框架&#xff1a; Anchor - a free Bootstrap UI Kit综合使用bootstrap框架做一个Aotm Blog个人博客_基于bootstrap的博客-CSDN博客 做出模板base.html {% load static %} <!DOCTYPE html> <html langen> <head><meta charset"UT…

Facebook账单户和海外户该如何选择?

近期&#xff0c;有不少小伙伴来咨询广告投放账户的问题&#xff0c;很多人把账单户作为广告投放的选择&#xff0c;那么账单户和海外户哪个更适合你呢&#xff1f;本文将详细探讨这两种账户类型的差异&#xff0c;以及在不同情境下应如何选择&#xff0c;感兴趣的朋友就继续看…

遨游双卫星智能终端,赋能石油行业安全生产和信息化建设

石油&#xff0c;被誉为“工业的血液”&#xff0c;其影响力深远&#xff0c;石油勘探与开发活动往往在人迹罕至的偏远区域展开&#xff0c;如广袤的戈壁滩、浩瀚的海洋&#xff0c;这些区域普遍缺乏健全的公共电信网络基础设施。以往&#xff0c;油田野外作业团队主要依赖短波…

避雷!Google Adsense联盟营销七大投放误区

你是否在使用Google AdSense进行广告投放&#xff1f;你是否想进一步优化你的投放策略&#xff1f;那么这篇文章你不可错过啦&#xff01; Google AdSense为跨境商家提供了一个平台&#xff0c;我们可以通过展示相关广告来赚取收入。然而&#xff0c;即使是最有经验的商家也可…

API项目:模拟接口开发和调用

创建模拟接口 controller 层&#xff1a; 控制层&#xff0c;负责处理用户请求&#xff0c;并根据请求调用相应的业务逻辑&#xff0c;然后返回对应的视图或数据。 model 层&#xff1a; 数据模型层&#xff0c;负责数据的处理和业务逻辑&#xff1b;在 model 层中&#xf…

无人机在矿业领域的应用!

矿区测绘与建模 无人机可以快速、全面地获取矿区的地形地貌数据&#xff0c;生成高精度的二维或三维模型。 这些模型可用于矿区的规划、设计、监测和管理&#xff0c;提高矿山的生产效率。 库存量量化监测 无人机能够捕捉厘米级的地形数据&#xff0c;通过计算得出准确的库…

ADC -模数转换

ADC -模数转换 - 将模拟信号转换为数字信号 目录 ADC -模数转换 - 将模拟信号转换为数字信号 STM32方面使用的AD转化方式是逐次逼近法 ADC 什么叫单次&#xff0c;连续&#xff0c;扫描&#xff0c;中断&#xff1f; 应用&#xff1a;运用STM32中ADC转…

Vue入门-小黑课堂Demo

功能需求&#xff1a; ①列表渲染 ②删除功能 ③添加功能 ④底部统计和清空 页面效果&#xff1a; 代码展示&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" c…

年会工作会议会务报名签到小程序开源版开发

年会工作会议会务报名签到小程序开源版开发 会议管理微信小程序&#xff0c;对会议流程、开支、数量、标准、供应商提供一种标准化的管理方法。以达到量化成本节约&#xff0c;风险缓解和服务质量提升的目的。适用于大型论坛、峰会、学术会议、政府大会、合作伙伴大会、经销商…

大多数人不知道的:线程池CallerRunsPolicy()拒绝策略

总所周知&#xff0c;java里面线程池的四个拒绝策略 AbortPolicy 丢弃并抛出RejectedExecutionException异常 DiscardPolicy 直接丢弃 DiscardOldestPolicy 直接丢弃最前面的任务&#xff0c;尝试执行新任务 CallerRunsPolicy 由调用线程池的线程处理任务&a…