constructor

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;// 构造函数注入@Autowiredpublic 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 {@Idprivate 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;// 使用有参构造函数进行依赖注入@Autowiredpublic 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 setterspublic 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;// 手动编写的构造函数@Autowiredpublic 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.mzph.cn/news/881302.shtml

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

相关文章

微知-如何临时设置Linux系统时间?(date -s “2024-10-08 22:55:00“, time, hwclock, timedatectl)

背景 在tar解压包的时候经常出现时间不对&#xff0c;可以临时用date命令修改一下&#xff0c;也可以其他&#xff0c;本文主要介绍临时修改的方法 date命令修改 sudo date -s "2024-10-08 22:55:00"其他查看和修改的命令 本文只记录查看方式&#xff0c;修改的暂…

详解正确创建好SpringBoot项目后但是找不到Maven的问题

目录 问题 解决步骤&#xff1a; 找到File->Project Structure... 设置SDK 设置SDKs 问题 刚刚在使用IDEA专业版创建好SpringBoot项目后&#xff0c;发现上方导航栏的运行按钮是灰色的&#xff0c;而且左侧导航栏的pom.xml的图标颜色也不是正常的&#xff0c;与此同时我…

SpringBoot Jar 包加密防止反编译

今天看到了一个说明jar包加密的实现方式&#xff0c;特意试了下效果&#xff0c;并下载了插件源码及实现源码查看了下子&#xff0c;感兴趣的可以在最后得到gitee地址。 SpringBoot 程序 Jar 包加密的方式&#xff0c;通过代码加密可以实现无法反编译。应用场景就是当需要把公司…

Linux防火墙-案例(二)snatdnat

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注作者&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 我们经过上小章节讲了Linux的部分进阶命令&#xff0c;我们接下来一章节来讲讲Linux防火墙。由于目前以云服务器为主&#x…

脑机接口技术的未来与现状:Neuralink、机械手臂与视觉假体的突破

近年来&#xff0c;脑机接口&#xff08;BCI&#xff09;技术发展迅速&#xff0c;不仅限于科幻小说和电影&#xff0c;已经逐步进入现实应用。特别是马斯克的Neuralink公司推出的“盲视&#xff08;Blindsight&#xff09;”设备&#xff0c;最近获得了FDA的突破性设备认定&am…

Spring Boot:打造下一代医院管理系统

3系统分析 3.1可行性分析 通过对本医院管理系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本医院管理系统采用JAVA作为开发语言&#xff0c;Spring Boot框…

动态规划算法题目练习——62.不同路径

1.题目解析 题目来源&#xff1a;62.不同路径——力扣 测试用例 2.算法原理 1.状态表示 这时由于避免越界初始化所以将左上角置为虚拟位置&#xff0c;创建一个二维dp表用来存储到当前为止的所有路径 2.状态转移方程 以dp[i,j]为例&#xff0c;起点到该位置的路径是起点到其上…

YOLO 二元分类器

YOLO 二元分类器 在评估二元分类器性能时&#xff0c;TP、FP、TN和FN是四个核心指标&#xff0c;它们分别代表真阳性、假阳性、真阴性和假阴性。以下是这些指标的定义、计算方法以及在实际应用中的意义&#xff1a; 定义 TP&#xff08;真阳性&#xff09;&#xff1a;模型正…

找不到concrt140.dll如何修复,快来试试这6种解决方法

concrt140.dll是微软Visual C 2015 Redistributable Package中的一个重要动态链接库文件&#xff0c;它在许多Windows应用程序中扮演着关键角色。本文将详细探讨concrt140.dll丢失的原因、影响、解决方法以及预防措施&#xff0c;帮助用户更好地理解和应对这一问题。 一、什么是…

【Verilog学习日常】—牛客网刷题—Verilog进阶挑战—VL45

异步FIFO 描述 请根据题目中给出的双口RAM代码和接口描述&#xff0c;实现异步FIFO&#xff0c;要求FIFO位宽和深度参数化可配置。 电路的接口如下图所示。 双口RAM端口说明&#xff1a; 端口名 I/O 描述 wclk input 写数据时钟 wenc input 写使能 waddr input 写…

算法知识点————贪心

贪心&#xff1a;只考虑局部最优解&#xff0c;不考虑全部最优解。有时候得不到最优解。 DP&#xff1a;考虑全局最优解。DP的特点&#xff1a;无后效性&#xff08;正在求解的时候不关心前面的解是怎么求的&#xff09;&#xff1b; 二者都是在求最优解的&#xff0c;都有最优…

Springboot 整合 durid

文章目录 Springboot 整合 druiddruid的优势配置参数使用整合 Druid配置数据源配置参数绑定配置参数配置监控页面配置拦截器 Springboot 整合 druid druid的优势 可以很好的监控 DB 池连接 和 SQL 的执行情况可以给数据库密码加密可以很方便的编写JDBC插件 配置参数 使用 整…

算法闭关修炼百题计划(四)

仅供个人复习 1.两数相加2.寻找峰值6.岛屿的最大面积3.最大数4.会议室5.最长连续序列6.寻找两个正序数组的中位数 1.两数相加 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请…

.NET CORE程序发布IIS后报错误 500.19

发布IIS后浏览时报错误500.19&#xff0c;同时配置文件web.config的路径中也存在问号“?”。 可能原因&#xff1a;没有安装运行时

ViT(Vision Transformer详解)

Transformer作为前沿的深度学习框架&#xff0c;带有多模态的特性&#xff0c;对于不同类型的输入数据&#xff0c;不管是文本还是图像均可进行处理&#xff0c;而ViT则是对于Transformer中的视觉方面&#xff08;也就是输入数据为图像&#xff09;的衍生物&#xff08;因Trans…

MATLAB - 浮动基座机器人的逆运动学

系列文章目录 前言 本例演示如何解决以浮动底座为模型的机器人的逆运动学问题。浮动底座机器人可以在空间中自由平移和旋转&#xff0c;具有六个自由度。浮动基座机器人的逆运动学问题适用于空间应用&#xff0c;即使用安装在浮动和致动基座上的机械臂在空间操纵物体&#xff0…

k8s 中的金丝雀发布(灰度发布)

目录 1 什么是金丝雀发布 2 Canary 发布方式 3 Canary 两种发布方式实操 3.1 准备工作 3.1.1 将 nginx 命名两个版本 v1 与 v2 3.1.2 暴露端口并指定微服务类型 3.1.3 进入 pod 修改默认发布文件 3.1.4 测试 service 是否正常 3.2 基于权重的灰度发布 3.2.1 创建 Igress 资源类…

MS SQL Server 实战 统计与汇总重复记录

目录 需求 范例运行环境 数据样本设计 功能实现 上传EXCEL文件到数据库 分组统计 SQL 语句 分组汇总 SQL 语句 having 语句过滤最终统计结果 小结 需求 在日常的数据管理应用中&#xff0c;统计和汇总重复记录的情况是经常遇到的一个问题&#xff0c;然后我们会根据统…

谢希仁计算机网络 (四)—— 网络层

计算机网络&#xff08;四&#xff09;—— 网络层&#xff08;1、2&#xff09;&#xff1a;网络层概述、网络层提供的两种服务 计算机网络&#xff08;四&#xff09;—— 网络层&#xff08;1、2&#xff09;&#xff1a;网络层概述、网络层提供的两种服务_以下属于网络层范…

IntelliJ IDEA 2024.2 新特性概览

文章目录 1、重点特性:1.1 改进的 Spring Data JPA 支持1.2 改进的 cron 表达式支持1.3 使用 GraalJS 作为 HTTP 客户端的执行引擎1.4 更快的编码时间1.5 K2 模式下的 Kotlin 性能和稳定性改进 2、用户体验2.1 改进的全行代码补全2.2 新 UI 成为所有用户的默认界面2.3 Search E…