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;修改的暂…

mysql 查出数据是乱序的

在 MySQL 中&#xff0c;如果你发现查询出来的数据是乱序的&#xff0c;这通常是因为没有指定 ORDER BY 子句。SQL 查询的结果集默认是不保证排序顺序的&#xff0c;除非明确指定了排序规则。 以下是一些解决方法和考虑事项&#xff1a; 1. 使用 ORDER BY 子句 在查询时&…

详解正确创建好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;通过代码加密可以实现无法反编译。应用场景就是当需要把公司…

【AI知识点】词袋模型(Bag-of-Words,BOW)

词袋模型&#xff08;Bag-of-Words&#xff0c;简称BOW&#xff09;是一种用于文本表示的简单且常用的方法&#xff0c;尤其在自然语言处理&#xff08;NLP&#xff09;和信息检索领域中广泛应用。词袋模型的核心思想是将文本表示为一个词频统计的集合&#xff0c;而不考虑词的…

Draw a triangle

Problem - E - Codeforces 题意:给定两个点的坐标求第三个点并且使得三个点围成的三角形面积最小&#xff1b; 这道题涉及了很多知识点&#xff1a; 1.在二维空间中&#xff0c;两个向量a,b叉乘&#xff0c;|a*b|在数值上等于以向量a和向量b为邻边构成的平行四边形的面积&am…

【Java】异常的处理-方式【主线学习笔记】

文章目录 前言1、处理概述2、Java异常处理机制&#xff08;方式&#xff09;方式一&#xff08;抓抛模型&#xff09;&#xff1a;try-catch-finally方式二&#xff1a;throws 异常类型总结 前言 Java是一门功能强大且广泛应用的编程语言&#xff0c;具有跨平台性和高效的执行…

螺蛳壳里做道场:老破机搭建的私人数据中心---Centos下Docker学习03(网络及IP规划)

3 网络及IP规划 3.1 容器连接网络初步规划 规划所有容器与虚拟机的三张网卡以macvlan的方式进行连接&#xff08;以后根据应用可以更改&#xff09;&#xff0c;在docker下创建nat、wifi、nei、wai四张网卡&#xff0c;他们和虚拟机及宿主机上NIC的相关连接参数如下表所示&am…

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;起点到该位置的路径是起点到其上…

费曼学习法没有输出对象怎么办?

‌费曼学习法并不需要输出对象。‌费曼学习法的核心在于通过将所学知识以简明易懂的方式解释给自己听&#xff0c;从而加深对知识的理解和记忆。这种方法强调的是理解和反思的过程&#xff0c;而不是简单地通过输出&#xff08;如向他人解释&#xff09;来检验学习效果。费曼学…

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;都有最优…

WPF下使用FreeRedis操作RedisStream实现简单的消息队列

Redis Stream简介 Redis Stream是随着5.0版本发布的一种新的Redis数据类型: 高效消费者组:允许多个消费者组从同一数据流的不同部分消费数据,每个消费者组都能独立地处理消息,这样可以并行处理和提高效率。 阻塞操作:消费者可以设置阻塞操作,这样它们会在流中有新数据…

Springboot 整合 durid

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

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

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