项目常用工具类

news/2024/10/19 7:26:13/

Java本身自带了许多非常好用的工具类,但有时我们的业务千奇百怪,自带的工具类又无法满足业务需求,需要在这些工具类的基础上进行二次封装改造。以下是在实际工作中,可能会使用到的工具类。

一、对象的序列化和反序列化

对象的序列化和反序列化有很多方式,这里介绍一下最常用的Jackson。

Jackson 是一个简单基于 Java 应用库,Jackson 可以轻松的将 Java 对象转换成 json 对象和 xml 文档,同样也可以将 json、xml 转换成 Java 对象。并且Jackson是开源免费的,源代码托管在 GitHub 上。

1.1 Jackson注解

Jackson 类库包含了很多注解,可以让我们快速建立 Java 类与 JSON 之间的关系。常用的注解如下所示:

  • @JsonProperty:用来修改序列化后的 JSON 属性名,默认情况下 JSON 属性名取对象中的属性名,也可以通过 value 属性指定 JSON 属性名。如果需要的话,该注解还有一个 index 属性指定生成 JSON 属性的顺序。
  • @JsonIgnore:用于排除某个属性,这样该属性就不会被 Jackson 序列化和反序列化。
  • @JsonIgnoreProperties:这个注解定义在类上的,用来排除对象中的某些属性。比如在序列化 JSON 的时候,@JsonIgnoreProperties({"prop1", "prop2"}) 会忽略 pro1 和 pro2 两个属性。在从 JSON 反序列化为 Java 类的时候,@JsonIgnoreProperties(ignoreUnknown=true) 会忽略所有没有 Getter 和 Setter 的属性。该注解在 Java 类和 JSON 不完全匹配的时候很有用。
  • @JsonIgnoreType:也是定义在类上的,会排除所有指定类型的属性。
  • @JsonPropertyOrder:@JsonPropertyOrder 和 @JsonProperty 的 index 属性类似,用来指定属性序列化时的顺序。
  • @JsonRootName:用于指定 JSON 根属性的名称。
  • @JsonInclude:@JsonInclude(JsonInclude.Include.NON_NULL):对值为 null 的属性不进行序列化
  • @JsonFormat:添加到需要指定格式的日期属性上,指定日期属性序列化与反序列化时的格式。timezone = “GMT+8” 设置时区,表示 +8 小时,否则会少8小时。ObjectMapper 序列化 POJO 对象为 json 字符串时,Date 日期类型默认会转为 long 长整型,json 字符串反序列化为 POJO 时自动将长整型的日期转为 Date 类型。

1.2 Jackson 的使用

第一步:导入依赖

jackson-databind 内部依赖了 jackson-annotations 与 jackson-core,所以 Maven 应用时,只要导入 databind 一个,则同时也导入了 annotations 与 core 依赖。

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.11.0</version>
</dependency>

如果是 springboot 项目,它内部已经包含了 Jackson,只需要引入 web 模块即可

二、时间相关

java">import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;/*** 时间工具类*/
@Slf4j
public class DateUtil {/*** 常用的时间模型常量*/public static final String PATTERN_DATE_TIME_MONTH = "yyyy-MM-dd";private static final String PATTERN_DATE_TIME = "yyyy-MM-dd HH:mm:ss";public static final String PATTERN_DATE_TIME_MILLISECOND = "yyyy-MM-dd HH:mm:ss.SSS";private static final String EXPORT_FORMAT_DATE_TIME = "yyyyMMdd-hhmmss";/*** 周末*/public static List<Integer> holidays = Lists.newArrayList(6, 7);/*** 工作日*/public static List<Integer> workdays = Lists.newArrayList(1, 2, 3, 4, 5);/*** 获取指定的format,每次重建避免线程安全问题 yyyy-MM-dd HH:mm:ss*/public static SimpleDateFormat getYyyyMmDdHhMmSs() {return new SimpleDateFormat(PATTERN_DATE_TIME);}/*** LocalDateTime转为String,格式为:"2023-10-13 15:40:23"*/public static String formatDateTime(LocalDateTime dateTime) {if (Objects.isNull(dateTime)) {return "";}DateTimeFormatter formatter = DateTimeFormatter.ofPattern(PATTERN_DATE_TIME);return dateTime.format(formatter);}/*** LocalDateTime转为String,格式为:"2023-10-13"*/public static String formatDateTimeOfMonth(LocalDateTime dateTime) {if (Objects.isNull(dateTime)) {return "";}DateTimeFormatter formatter = DateTimeFormatter.ofPattern(PATTERN_DATE_TIME_MONTH);return dateTime.format(formatter);}/*** LocalDateTime转为Date*/public static Date localDateTimeToDate(LocalDateTime localDateTime) {return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());}/*** LocalDateTime转为时间戳*/public static String dateTimestamp(LocalDateTime date) {return DateTimeFormatter.ofPattern("yyMMddHHmmssSSS").format(date);}/*** LocalDateTime转为String,自定义时间格式** @param dateTime LocalDateTime类型的时间* @param pattern  自定义的时间格式*/public static String formatDateTime(LocalDateTime dateTime, String pattern) {if (Objects.isNull(dateTime)) {return "";}DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);return dateTime.format(formatter);}/*** Date转为String,格式为:“2023-01-01”*/public static String formatDateTime(Date dateTime) {if (Objects.nonNull(dateTime)) {return DateFormatUtils.format(dateTime, PATTERN_DATE_TIME_MONTH);}return "";}/*** Date转为String,格式为:“2023-01-01 12:10:50”*/public static String formatDateOfDate(Date dateTime) {if (Objects.nonNull(dateTime)) {return DateFormatUtils.format(dateTime, PATTERN_DATE_TIME);}return "";}/*** Date转为String,格式为:“20230101-121050”*/public static String exportFormatDateTime(Date dateTime) {if (Objects.nonNull(dateTime)) {return DateFormatUtils.format(dateTime, EXPORT_FORMAT_DATE_TIME);}return "";}/*** Date转为String,格式为:“2023.01.01”*/public static String formatDate(Date dateTime) {if (Objects.nonNull(dateTime)) {return DateFormatUtils.format(dateTime, "yyyy.MM.dd");}return "";}/*** Date转为String时间,自定义时间格式** @param dateTime Date时间* @param pattern  自定义的时间格式*/public static String formatDateTime(Date dateTime, String pattern) {if (Objects.nonNull(dateTime)) {return DateFormatUtils.format(dateTime, pattern);}return "";}/*** 字符串时间转为Date,格式为:"Sun Oct 01 00:00:00 CST 2023"*/public static Date strToDateTimeOfMonth(String strDate) {try {strDate = strDate.substring(0, 10);return DateUtils.parseDate(strDate, PATTERN_DATE_TIME_MONTH);} catch (ParseException e) {log.error("时间转换异常:{}", e.getMessage());throw new RuntimeException(e);}}/*** 字符串时间转为Date,格式为:"Sun Oct 01 02:56:20 CST 2023"*/public static Date strToDateTime(String strDate) {if (strDate.length() != 19) {throw new RuntimeException("入参时间格式不正确");}try {return DateUtils.parseDate(strDate, PATTERN_DATE_TIME);} catch (ParseException e) {log.error("时间转换异常:{}", e.getMessage());throw new RuntimeException(e);}}/*** 将Date对象转化为指定格式dateFormat的字符串** @return String*/public static String getDate(Date date, String dateFormat) {SimpleDateFormat format = new SimpleDateFormat(dateFormat);return format.format(date);}/*** 将指定格式fromFormat的Date字符串转化为Date对象*/public static Date getDate(String date) {SimpleDateFormat sdf = getYyyyMmDdHhMmSs();try {return sdf.parse(date);} catch (Exception e) {e.printStackTrace();}return null;}/*** 将指定格式fromFormat的Date字符串转化为Date对象** @return Date*/public static Date getDate(String date, String fromFormat) {try {SimpleDateFormat fromSimpleDateFormat = new SimpleDateFormat(fromFormat);return fromSimpleDateFormat.parse(date);} catch (Exception e) {e.printStackTrace();}return null;}/*** 字符串时间转为LocalDateTime,格式为:"2023-10-01T02:56:20"*/public static LocalDateTime strToLocalDateTime(String strDate) {if (strDate.length() != 19) {throw new RuntimeException("入参时间格式不正确");}try {Date date = DateUtils.parseDate(strDate, "yyyy-MM-dd HH:mm:ss");return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();} catch (ParseException e) {log.error("时间转换异常:{}", e.getMessage());throw new RuntimeException(e);}}/*** 字符串时间转为LocalDateTime,格式为:"2023-10-01T02:56:20.001"*/public static LocalDateTime strToLocalDateTimeMillisecond(String strDate) {try {if (strDate.length() != 23) {throw new RuntimeException("入参时间格式不正确");}Date date = DateUtils.parseDate(strDate, PATTERN_DATE_TIME_MILLISECOND);return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();} catch (ParseException e) {log.error("时间转换异常:{}", e.getMessage());throw new RuntimeException(e);}}/*** 计算两个时间差*/public static String getDatePoor(Date endDate, Date nowDate) {long nd = 1000 * 24 * 60 * 60;long nh = 1000 * 60 * 60;long nm = 1000 * 60;// long ns = 1000;// 获得两个时间的毫秒时间差异long diff = Math.abs(endDate.getTime() - nowDate.getTime());// 计算差多少天long day = diff / nd;// 计算差多少小时long hour = diff % nd / nh;// 计算差多少分钟long min = diff % nd % nh / nm;// 计算差多少秒//输出结果// long sec = diff % nd % nh % nm / ns;return day + "天" + hour + "小时" + min + "分钟";}/*** 计算两个时间相差天数*/public static int differentDaysByMillisecond(Date date1, Date date2) {return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));}/*** 计算两个时间相差小时*/public static int differentHourByMillisecond(Date date1, Date date2) {return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600)));}/*** 计算两个时间相差分钟*/public static int differentMinByMillisecond(Date date1, Date date2) {return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 60)));}/*** 获得某天最大时间,例如:Wed Nov 29 23:59:59 CST 2023*/public static Date getEndOfDay(Date date) {LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX);return Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant());}/*** 获得某天最小时间,例如:Wed Nov 29 00:00:00 CST 2023*/public static Date getStartOfDay(Date date) {LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());LocalDateTime startOfDay = localDateTime.with(LocalTime.MIN);return Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant());}/*** 获取相对于date前后的某一天*/public static Date anotherDay(Date date, int i) {Calendar cal = Calendar.getInstance();cal.setTime(date);cal.add(Calendar.DATE, i);return cal.getTime();}/*** 给定值向后加月份*/public static Date stepMonth(Date sourceDate, int month) {Calendar c = Calendar.getInstance();c.setTime(sourceDate);c.add(Calendar.MONTH, month);return c.getTime();}/*** 给定值向后加年份*/public static Date stepYear(Date sourceDate, int year) {Calendar c = Calendar.getInstance();c.setTime(sourceDate);c.add(Calendar.YEAR, year);return c.getTime();}/*** 该年最后一天的 时、分、秒以23:59:59结尾*/public static Date dateTimeYearEndWidth(Date dateTime) {String dateTimeString = getDate(dateTime, PATTERN_DATE_TIME);return getDate(dateTimeString.substring(0, 4) + "-12-31 23:59:59");}/*** 获取过去N天内的日期数组(不包含今天)返回的时间类型为:yyyy-MM-dd*/public static ArrayList<String> getLastDays(int intervals) {ArrayList<String> pastDaysList = new ArrayList<>();for (int i = intervals; i > 0; i--) {Calendar calendar = Calendar.getInstance();calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - i);Date today = calendar.getTime();SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");pastDaysList.add(format.format(today));}return pastDaysList;}}

三、正则校验

java">import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** 正则相关工具类*/
public class ValidateUtil {/*** 手机号(简单),以1开头的11位纯数字*/public static final String REGEX_MOBILE_SIMPLE = "^[1]\\d{10}$";/*** 手机号(精确)* <p>移动:134(0-8)、135、136、137、138、139、147、150、151、152、157、158、159、178、182、183、184、187、188</p>* <p>联通:130、131、132、145、155、156、175、176、185、186</p>* <p>电信:133、153、173、177、180、181、189</p>* <p>全球星:1349</p>* <p>虚拟运营商:170</p>*/public static final String REGEX_MOBILE_EXACT = "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|(147))\\d{8}$";/*** 固定电话号码*/public static final String REGEX_TEL = "^0\\d{2,3}[- ]?\\d{7,8}";/*** 身份证号(15位身份证号)*/public static final String REGEX_ID_CARD15 = "^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$";/*** 身份证号(18位身份证号)*/public static final String REGEX_ID_CARD18 = "^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9Xx])$";/*** 身份证号(15和18位)*/public static final String REGEX_ID_CARD15AND18 = "(^\\d{8}(0\\d|10|11|12)([0-2]\\d|30|31)\\d{3}$)|(^\\d{6}(18|19|20)\\d{2}(0\\d|10|11|12)([0-2]\\d|30|31)\\d{3}(\\d|X|x)$)";/*** 邮箱*/public static final String REGEX_EMAIL = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$";/*** 网址URL*/public static final String REGEX_URL = "[a-zA-z]+://[^\\s]*";/*** 汉字*/public static final String REGEX_ZH = "^[\\u4e00-\\u9fa5]+$";/*** 用户名(取值范围为a-z,A-Z,0-9,"_",汉字,不能以"_"结尾,用户名必须是6-20位)*/public static final String REGEX_USERNAME = "^[\\w\\u4e00-\\u9fa5]{6,20}(?<!_)$";/*** yyyy-MM-dd格式的日期校验,已考虑平闰年*/public static final String REGEX_DATE = "^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$";/*** IP地址*/public static final String REGEX_IP = "((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)";/*** 双字节字符(包括汉字在内)*/public static final String REGEX_DOUBLE_BYTE_CHAR = "[^\\x00-\\xff]";/*** 空白行*/public static final String REGEX_BLANK_LINE = "\\n\\s*\\r";/*** QQ号*/public static final String REGEX_TENCENT_NUM = "[1-9][0-9]{4,}";/*** 中国邮政编码*/public static final String REGEX_ZIP_CODE = "[1-9]\\d{5}(?!\\d)";/*** 正整数*/public static final String REGEX_POSITIVE_INTEGER = "^[1-9]\\d*$";/*** 负整数*/public static final String REGEX_NEGATIVE_INTEGER = "^-[1-9]\\d*$";/*** 整数*/public static final String REGEX_INTEGER = "^-?[1-9]\\d*$";/*** 非负整数(正整数 + 0)*/public static final String REGEX_NOT_NEGATIVE_INTEGER = "^[1-9]\\d*|0$";/*** 非正整数(负整数 + 0)*/public static final String REGEX_NOT_POSITIVE_INTEGER = "^-[1-9]\\d*|0$";/*** 正浮点数*/public static final String REGEX_POSITIVE_FLOAT = "^[1-9]\\d*\\.\\d*|0\\.\\d*[1-9]\\d*$";/*** 负浮点数*/public static final String REGEX_NEGATIVE_FLOAT = "^-[1-9]\\d*\\.\\d*|-0\\.\\d*[1-9]\\d*$";/*** 验证手机号(简单)** @param input 待验证文本* @return true: 匹配 <br> false: 不匹配*/public static boolean isMobileSimple(CharSequence input) {return isMatch(REGEX_MOBILE_SIMPLE, input);}/*** 验证手机号(精确)** @param input 待验证文本* @return true: 匹配 <br> false: 不匹配*/public static boolean isMobileExact(CharSequence input) {return isMatch(REGEX_MOBILE_EXACT, input);}/*** 验证固定电话号码** @param input 待验证文本* @return true: 匹配 <br> false: 不匹配*/public static boolean isTel(CharSequence input) {return isMatch(REGEX_TEL, input);}/*** 验证身份证号码(15位)** @param input 待验证文本* @return true: 匹配 <br> false: 不匹配*/public static boolean isIdCard15(CharSequence input) {return isMatch(REGEX_ID_CARD15, input);}/*** 验证身份证号码(18位)** @param input 待验证文本* @return true: 匹配 <br> false: 不匹配*/public static boolean isIdCard18(CharSequence input) {return isMatch(REGEX_ID_CARD18, input);}/*** 验证身份证号码(15/18位)** @param input 待验证文本* @return true: 匹配 <br> false: 不匹配*/public static boolean isIdCard15and18(CharSequence input) {return isMatch(REGEX_ID_CARD15AND18, input);}/*** 验证邮箱** @param input 待验证文本* @return true: 匹配 <br> false: 不匹配*/public static boolean isEmail(CharSequence input) {return isMatch(REGEX_EMAIL, input);}/*** 验证网址URL** @param input 待验证文本* @return true: 匹配 <br> false: 不匹配*/public static boolean isUrl(CharSequence input) {return isMatch(REGEX_URL, input);}/*** 验证汉字** @param input 待验证文本* @return true: 匹配 <br> false: 不匹配*/public static boolean isZh(CharSequence input) {return isMatch(REGEX_ZH, input);}/*** 验证用户名(取值范围为a-z,A-Z,0-9,"_",汉字,不能以"_"结尾,用户名必须是6-20位)** @param input 待验证文本* @return true: 匹配 <br> false: 不匹配*/public static boolean isUsername(CharSequence input) {return isMatch(REGEX_USERNAME, input);}/*** 验证yyyy-MM-dd格式的日期校验,已考虑平闰年** @param input 待验证文本* @return true: 匹配 <br> false: 不匹配*/public static boolean isDate(CharSequence input) {return isMatch(REGEX_DATE, input);}/*** 验证IP地址** @param input 待验证文本* @return true: 匹配 <br> false: 不匹配*/public static boolean isIp(CharSequence input) {return isMatch(REGEX_IP, input);}/*** 判断是否匹配正则** @param regex 正则表达式* @param input 要匹配的字符串* @return true: 匹配 <br> false: 不匹配*/public static boolean isMatch(String regex, CharSequence input) {return input != null && input.length() > 0 && Pattern.matches(regex, input);}/*** 获取正则匹配的部分** @param regex 正则表达式* @param input 要匹配的字符串* @return 正则匹配的部分*/public static List<String> getMatches(String regex, CharSequence input) {if (input == null) {return null;}List<String> matches = new ArrayList<>();Pattern pattern = Pattern.compile(regex);Matcher matcher = pattern.matcher(input);while (matcher.find()) {matches.add(matcher.group());}return matches;}/*** 获取正则匹配分组** @param input 要分组的字符串* @param regex 正则表达式* @return 正则匹配分组*/public static String[] getSplits(String input, String regex) {if (input == null) {return null;}return input.split(regex);}/*** 替换正则匹配的第一部分** @param input       要替换的字符串* @param regex       正则表达式* @param replacement 代替者* @return 替换正则匹配的第一部分*/public static String getReplaceFirst(String input, String regex, String replacement) {if (input == null) {return null;}return Pattern.compile(regex).matcher(input).replaceFirst(replacement);}/*** 替换所有正则匹配的部分** @param input       要替换的字符串* @param regex       正则表达式* @param replacement 代替者* @return 替换所有正则匹配的部分*/public static String getReplaceAll(String input, String regex, String replacement) {if (input == null) {return null;}return Pattern.compile(regex).matcher(input).replaceAll(replacement);}}

四、JWT

第一步:导入坐标

<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version>
</dependency>

第二步:在项目导入jwt工具类

java">import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;import java.util.Date;
import java.util.Map;
import java.util.Optional;/*** jwt的token生成与解析*/
@Slf4j
@Component
public class JwtUtils {/*** token秘钥,请勿泄露,请勿随便修改*/@Value("${mallchat.jwt.secret}")private String secret;private static final String UID_CLAIM = "uid";private static final String CREATE_TIME = "createTime";/*** JWT生成Token* JWT构成: header, payload, signature*/public String createToken(Long uid) {String token = JWT.create().withClaim(UID_CLAIM, uid) //只存一个uid信息,其他的自己去redis查.withClaim(CREATE_TIME, new Date()).sign(Algorithm.HMAC256(secret)); //signaturereturn token;}/*** 解密Token*/public Map<String, Claim> verifyToken(String token) {if (StringUtils.isEmpty(token)) {return null;}try {JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secret)).build();DecodedJWT jwt = verifier.verify(token);return jwt.getClaims();} catch (Exception e) {log.error("decode error,token:{}", token, e);}return null;}/*** 根据Token获取uid*/public Long getUidOrNull(String token) {return Optional.ofNullable(verifyToken(token)).map(map -> map.get(UID_CLAIM)).map(Claim::asLong).orElse(null);}}


http://www.ppmy.cn/news/1432825.html

相关文章

支付宝支付之SpringBoot整合支付宝入门

文章目录 支付宝支付对接流程核心所需的参数申请注册配置开发信息接口加签方式 发起支付订单案例门店直连方式商家/服务商后台转发方式安全设计支付pom.xmlapplication.ymlAlipayController.java统一收单线下交易业务请求参数CURL请求示例实例代码 查询撤销重要入参说明重要出参…

路由引入,路由过滤,路由策略实验

1&#xff0c;配置IP地址 R1&#xff1a; [R1]dis ip interface brief Interface IP Address/Mask Physical Protocol GigabitEthernet0/0/0 100.1.1.1/24 up up LoopBack0 …

[lesson49]多态的概念和意义

多态的概念和意义 函数重写回顾 父类中被重写的函数依然会继承给子类 子类中重写的函数将覆盖父类中的函数 通过作用域分辨符(::)访问父类中的同名成员 多态的概念和意义 面向对象中期望的行为 根据实际的对象类型判断如何调用重写函数父类指针(引用)指向 父类对象则调用…

ChatGPT引领:打造独具魅力的论文

ChatGPT无限次数:点击直达 ChatGPT引领&#xff1a;打造独具魅力的论文 在数字化时代&#xff0c;人工智能技术的快速发展不仅改变了我们生活的方方面面&#xff0c;还在学术研究领域展现出更广阔的可能性。其中&#xff0c;自然语言生成模型ChatGPT凭借其强大的生成能力和智能…

低代码技术与仓储管理的新纪元:革命性的供应链变革

引言 在当今数字化时代&#xff0c;企业对于创新和效率的追求越发迫切。在这样的背景下&#xff0c;低代码技术应运而生&#xff0c;成为企业数字化转型的重要工具之一。低代码技术的崛起为企业提供了一种快速、灵活、成本效益高的开发方式&#xff0c;大大缩短了软件开发周期…

JavaScript算数运算符

源码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </head> <b…

【webrtc】m114自己实现的PrioritizedPacketQueue及优先级处理

G:\CDN\WEBRTC-DEV\libwebrtc_build\src\modules\pacing\prioritized_packet_queue.h跟m98不同 :webrtc】m98 RoundRobinPacketQueue的优先级处理,m114直接使用taskqueue顺序处理了。甚至自己实现了优先级队列感觉简化了实现,更为清晰 易读,但是去掉了码率低就优先的逻辑。1…

电磁兼容(EMC):静电放电(ESD)抗扰度试验深度解读(六)

目录 1. 静电测试干扰方式 2. 案例一 3. 案例二 4. 案例三 5. 案例四 6. 总结 静电放电测试的复杂性决定了这项测试对产品的主要影响方式也是多样的。标准里介绍了几种常见的影响方式&#xff1a; 1. 静电测试干扰方式 在静电放电试验中&#xff0c;测试了受试设备对于…