mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-05 17:37:59 +08:00
Prepare release
This commit is contained in:
commit
a0c65de743
26
CHANGELOG.md
26
CHANGELOG.md
@ -3,6 +3,27 @@
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# 5.8.1 (2022-05-16)
|
||||
|
||||
### 🐣新特性
|
||||
* 【core 】 BooleanUtil增加toBooleanObject方法(issue#I56AG3@Gitee)
|
||||
* 【core 】 CharSequenceUtil增加startWithAnyIgnoreCase方法(issue#2312@Github)
|
||||
* 【system 】 JavaInfo增加版本(issue#2310@Github)
|
||||
* 【core 】 新增CastUtil(pr#2313@Github)
|
||||
* 【core 】 ByteUtil新增bytesToShort重载(issue#I57FA7@Gitee)
|
||||
* 【core 】 ReflectUtil.invoke方法抛出运行时异常增加InvocationTargetRuntimeException(issue#I57GI2@Gitee)
|
||||
* 【core 】 NumberUtil.parseNumber支持16进制(issue#2328@Github)
|
||||
*
|
||||
### 🐞Bug修复
|
||||
* 【core 】 MapUtil.map对null友好,且修复了测试用例中分组问题(pr#614@Gitee)
|
||||
* 【core 】 修复BeanUtil.beanToMap中properties为null的空指针问题(issue#2303@Github)
|
||||
* 【db 】 DialectName中修正为POSTGRESQL(issue#2308@Github)
|
||||
* 【core 】 修复BeanPath无法识别引号内的内容问题(issue#I56DE0@Gitee)
|
||||
* 【core 】 修复Map.entry方法返回可变不可变相反问题
|
||||
* 【jwt 】 修复jwt的过期容忍时间问题(issue#2329@Gitee)
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# 5.8.0 (2022-05-06)
|
||||
|
||||
### ❌不兼容特性
|
||||
@ -174,4 +195,7 @@
|
||||
* 【core 】 FileUtil.getMimeType增加rar、7z支持(issue#I4ZBN0@Gitee)
|
||||
* 【json 】 JSON修复transient设置无效问题(issue#2212@Github)
|
||||
* 【core 】 修复IterUtil.getElementType获取结果为null的问题(issue#2222@Github)
|
||||
* 【core 】 修复农历转公历在闰月时错误(issue#I4ZSGJ@Gitee)
|
||||
* 【core 】 修复农历转公历在闰月时错误(issue#I4ZSGJ@Gitee)
|
||||
|
||||
# 5.7.x 或更早版本
|
||||
* [https://gitee.com/dromara/hutool/blob/v5-master/CHANGELOG_5.0-5.7.md](https://gitee.com/dromara/hutool/blob/v5-master/CHANGELOG_5.0-5.7.md)
|
@ -144,18 +144,18 @@ We provide the T-Shirt and Sweater with Hutool Logo, please visit the shop:
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
### 🍐Gradle
|
||||
```
|
||||
implementation 'cn.hutool:hutool-all:5.8.0'
|
||||
implementation 'cn.hutool:hutool-all:5.8.1'
|
||||
```
|
||||
|
||||
## 📥Download
|
||||
|
||||
- [Maven Repo](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.8.0/)
|
||||
- [Maven Repo](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.8.1/)
|
||||
|
||||
> 🔔️note:
|
||||
> Hutool 5.x supports JDK8+ and is not tested on Android platforms, and cannot guarantee that all tool classes or tool methods are available.
|
||||
|
@ -144,20 +144,20 @@ Hutool的存在就是为了减少代码搜索成本,避免网络上参差不
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
### 🍐Gradle
|
||||
```
|
||||
implementation 'cn.hutool:hutool-all:5.8.0'
|
||||
implementation 'cn.hutool:hutool-all:5.8.1'
|
||||
```
|
||||
|
||||
### 📥下载jar
|
||||
|
||||
点击以下链接,下载`hutool-all-X.X.X.jar`即可:
|
||||
|
||||
- [Maven中央库](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.8.0/)
|
||||
- [Maven中央库](https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.8.1/)
|
||||
|
||||
> 🔔️注意
|
||||
> Hutool 5.x支持JDK8+,对Android平台没有测试,不能保证所有工具类或工具方法可用。
|
||||
|
@ -1 +1 @@
|
||||
5.8.0
|
||||
5.8.1
|
||||
|
@ -1 +1 @@
|
||||
var version = '5.8.0'
|
||||
var version = '5.8.1'
|
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hutool-all</artifactId>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hutool-aop</artifactId>
|
||||
@ -19,7 +19,7 @@
|
||||
<properties>
|
||||
<!-- versions -->
|
||||
<cglib.version>3.3.0</cglib.version>
|
||||
<spring.version>5.3.19</spring.version>
|
||||
<spring.version>5.3.20</spring.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hutool-bloomFilter</artifactId>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hutool-bom</artifactId>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hutool-cache</artifactId>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hutool-captcha</artifactId>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hutool-core</artifactId>
|
||||
|
@ -1,9 +1,9 @@
|
||||
package cn.hutool.core.bean;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.text.StrBuilder;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.CharUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
@ -11,7 +11,6 @@ import cn.hutool.core.util.StrUtil;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -68,7 +67,7 @@ public class BeanPath implements Serializable{
|
||||
* @param expression 表达式
|
||||
* @return BeanPath
|
||||
*/
|
||||
public static BeanPath create(String expression) {
|
||||
public static BeanPath create(final String expression) {
|
||||
return new BeanPath(expression);
|
||||
}
|
||||
|
||||
@ -77,17 +76,26 @@ public class BeanPath implements Serializable{
|
||||
*
|
||||
* @param expression 表达式
|
||||
*/
|
||||
public BeanPath(String expression) {
|
||||
public BeanPath(final String expression) {
|
||||
init(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表达式解析后的分段列表
|
||||
*
|
||||
* @return 表达式分段列表
|
||||
*/
|
||||
public List<String> getPatternParts(){
|
||||
return this.patternParts;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Bean中对应表达式的值
|
||||
*
|
||||
* @param bean Bean对象或Map或List等
|
||||
* @return 值,如果对应值不存在,则返回null
|
||||
*/
|
||||
public Object get(Object bean) {
|
||||
public Object get(final Object bean) {
|
||||
return get(this.patternParts, bean, false);
|
||||
}
|
||||
|
||||
@ -104,10 +112,16 @@ public class BeanPath implements Serializable{
|
||||
* @param bean Bean、Map或List
|
||||
* @param value 值
|
||||
*/
|
||||
public void set(Object bean, Object value) {
|
||||
public void set(final Object bean, final Object value) {
|
||||
set(bean, this.patternParts, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.patternParts.toString();
|
||||
}
|
||||
|
||||
//region Private Methods
|
||||
/**
|
||||
* 设置表达式指定位置(或filed对应)的值<br>
|
||||
* 若表达式指向一个List则设置其坐标对应位置的值,若指向Map则put对应key的值,Bean则设置字段的值<br>
|
||||
@ -122,7 +136,7 @@ public class BeanPath implements Serializable{
|
||||
* @param patternParts 表达式块列表
|
||||
* @param value 值
|
||||
*/
|
||||
private void set(Object bean, List<String> patternParts, Object value) {
|
||||
private void set(final Object bean, final List<String> patternParts, final Object value) {
|
||||
Object subBean = get(patternParts, bean, true);
|
||||
if(null == subBean) {
|
||||
set(bean, patternParts.subList(0, patternParts.size() - 1), new HashMap<>());
|
||||
@ -132,7 +146,6 @@ public class BeanPath implements Serializable{
|
||||
BeanUtil.setFieldValue(subBean, patternParts.get(patternParts.size() - 1), value);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------- Private method start
|
||||
/**
|
||||
* 获取Bean中对应表达式的值
|
||||
*
|
||||
@ -141,7 +154,7 @@ public class BeanPath implements Serializable{
|
||||
* @param ignoreLast 是否忽略最后一个值,忽略最后一个值则用于set,否则用于read
|
||||
* @return 值,如果对应值不存在,则返回null
|
||||
*/
|
||||
private Object get(List<String> patternParts, Object bean, boolean ignoreLast) {
|
||||
private Object get(final List<String> patternParts, final Object bean, final boolean ignoreLast) {
|
||||
int length = patternParts.size();
|
||||
if (ignoreLast) {
|
||||
length--;
|
||||
@ -166,7 +179,7 @@ public class BeanPath implements Serializable{
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Object getFieldValue(Object bean, String expression) {
|
||||
private static Object getFieldValue(final Object bean, final String expression) {
|
||||
if (StrUtil.isBlank(expression)) {
|
||||
return null;
|
||||
}
|
||||
@ -174,8 +187,8 @@ public class BeanPath implements Serializable{
|
||||
if (StrUtil.contains(expression, ':')) {
|
||||
// [start:end:step] 模式
|
||||
final List<String> parts = StrUtil.splitTrim(expression, ':');
|
||||
int start = Integer.parseInt(parts.get(0));
|
||||
int end = Integer.parseInt(parts.get(1));
|
||||
final int start = Integer.parseInt(parts.get(0));
|
||||
final int end = Integer.parseInt(parts.get(1));
|
||||
int step = 1;
|
||||
if (3 == parts.size()) {
|
||||
step = Integer.parseInt(parts.get(2));
|
||||
@ -218,13 +231,14 @@ public class BeanPath implements Serializable{
|
||||
*
|
||||
* @param expression 表达式
|
||||
*/
|
||||
private void init(String expression) {
|
||||
List<String> localPatternParts = new ArrayList<>();
|
||||
int length = expression.length();
|
||||
private void init(final String expression) {
|
||||
final List<String> localPatternParts = new ArrayList<>();
|
||||
final int length = expression.length();
|
||||
|
||||
final StrBuilder builder = StrUtil.strBuilder();
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
char c;
|
||||
boolean isNumStart = false;// 下标标识符开始
|
||||
boolean isInWrap = false; //标识是否在引号内
|
||||
for (int i = 0; i < length; i++) {
|
||||
c = expression.charAt(i);
|
||||
if (0 == i && '$' == c) {
|
||||
@ -233,7 +247,13 @@ public class BeanPath implements Serializable{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ArrayUtil.contains(EXP_CHARS, c)) {
|
||||
if('\'' == c){
|
||||
// 结束
|
||||
isInWrap = (false == isInWrap);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (false == isInWrap && ArrayUtil.contains(EXP_CHARS, c)) {
|
||||
// 处理边界符号
|
||||
if (CharUtil.BRACKET_END == c) {
|
||||
// 中括号(数字下标)结束
|
||||
@ -253,9 +273,9 @@ public class BeanPath implements Serializable{
|
||||
// 每一个边界符之前的表达式是一个完整的KEY,开始处理KEY
|
||||
}
|
||||
if (builder.length() > 0) {
|
||||
localPatternParts.add(unWrapIfPossible(builder));
|
||||
localPatternParts.add(builder.toString());
|
||||
}
|
||||
builder.reset();
|
||||
builder.setLength(0);
|
||||
} else {
|
||||
// 非边界符号,追加字符
|
||||
builder.append(c);
|
||||
@ -267,25 +287,12 @@ public class BeanPath implements Serializable{
|
||||
throw new IllegalArgumentException(StrUtil.format("Bad expression '{}':{}, we find '[' but no ']' !", expression, length - 1));
|
||||
} else {
|
||||
if (builder.length() > 0) {
|
||||
localPatternParts.add(unWrapIfPossible(builder));
|
||||
localPatternParts.add(builder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// 不可变List
|
||||
this.patternParts = Collections.unmodifiableList(localPatternParts);
|
||||
this.patternParts = ListUtil.unmodifiable(localPatternParts);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对于非表达式去除单引号
|
||||
*
|
||||
* @param expression 表达式
|
||||
* @return 表达式
|
||||
*/
|
||||
private static String unWrapIfPossible(CharSequence expression) {
|
||||
if (StrUtil.containsAny(expression, " = ", " > ", " < ", " like ", ",")) {
|
||||
return expression.toString();
|
||||
}
|
||||
return StrUtil.unWrap(expression, '\'');
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------- Private method end
|
||||
//endregion
|
||||
}
|
||||
|
@ -616,14 +616,16 @@ public class BeanUtil {
|
||||
* @since 5.8.0
|
||||
*/
|
||||
public static Map<String, Object> beanToMap(Object bean, String... properties) {
|
||||
int mapSize = 16;
|
||||
Editor<String> keyEditor = null;
|
||||
if(ArrayUtil.isNotEmpty(properties)){
|
||||
mapSize = properties.length;
|
||||
final Set<String> propertiesSet = CollUtil.set(false, properties);
|
||||
keyEditor = property -> propertiesSet.contains(property) ? property : null;
|
||||
}
|
||||
|
||||
// 指明了要复制的属性 所以不忽略null值
|
||||
return beanToMap(bean, new LinkedHashMap<>(properties.length, 1), false, keyEditor);
|
||||
return beanToMap(bean, new LinkedHashMap<>(mapSize, 1), false, keyEditor);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1058,7 +1058,7 @@ public class CollUtil {
|
||||
* @param <T> 集合元素类型
|
||||
* @param <K> 唯一键类型
|
||||
* @param collection 集合
|
||||
* @param override 是否覆盖模式,如果为{@code true},加入的新值会覆盖相同key的旧值,否则会忽略新加值
|
||||
* @param override 是否覆盖模式,如果为{@code true},加入的新值会覆盖相同key的旧值,否则会忽略新加值
|
||||
* @return {@link ArrayList}
|
||||
* @since 5.8.0
|
||||
*/
|
||||
|
118
hutool-core/src/main/java/cn/hutool/core/convert/CastUtil.java
Normal file
118
hutool-core/src/main/java/cn/hutool/core/convert/CastUtil.java
Normal file
@ -0,0 +1,118 @@
|
||||
package cn.hutool.core.convert;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 转换工具类,提供集合、Map等向上向下转换工具
|
||||
*
|
||||
* @author looly
|
||||
* @since 5.8.1
|
||||
*/
|
||||
public class CastUtil {
|
||||
/**
|
||||
* 泛型集合向上转型。例如将Collection<Integer>转换为Collection<Number>
|
||||
*
|
||||
* @param collection 集合
|
||||
* @param <T> 元素类型
|
||||
* @return 转换后的集合
|
||||
* @since 5.8.1
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Collection<T> castUp(Collection<? extends T> collection) {
|
||||
return (Collection<T>) collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* 泛型集合向下转型。例如将Collection<Number>转换为Collection<Integer>
|
||||
*
|
||||
* @param collection 集合
|
||||
* @param <T> 元素类型
|
||||
* @return 转换后的集合
|
||||
* @since 5.8.1
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Collection<T> castDown(Collection<? super T> collection) {
|
||||
return (Collection<T>) collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* 泛型集合向上转型。例如将Set<Integer>转换为Set<Number>
|
||||
*
|
||||
* @param set 集合
|
||||
* @param <T> 泛型
|
||||
* @return 泛化集合
|
||||
* @since 5.8.1
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Set<T> castUp(Set<? extends T> set) {
|
||||
return (Set<T>) set;
|
||||
}
|
||||
|
||||
/**
|
||||
* 泛型集合向下转型。例如将Set<Number>转换为Set<Integer>
|
||||
*
|
||||
* @param set 集合
|
||||
* @param <T> 泛型子类
|
||||
* @return 泛化集合
|
||||
* @since 5.8.1
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Set<T> castDown(Set<? super T> set) {
|
||||
return (Set<T>) set;
|
||||
}
|
||||
|
||||
/**
|
||||
* 泛型接口向上转型。例如将List<Integer>转换为List<Number>
|
||||
*
|
||||
* @param list 集合
|
||||
* @param <T> 泛型的父类
|
||||
* @return 泛化集合
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> List<T> castUp(List<? extends T> list) {
|
||||
return (List<T>) list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 泛型集合向下转型。例如将List<Number>转换为List<Integer>
|
||||
*
|
||||
* @param list 集合
|
||||
* @param <T> 泛型的子类
|
||||
* @return 泛化集合
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> List<T> castDown(List<? super T> list) {
|
||||
return (List<T>) list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 泛型集合向下转型。例如将Map<Integer, Integer>转换为Map<Number,Number>
|
||||
*
|
||||
* @param map 集合
|
||||
* @param <K> 泛型父类
|
||||
* @param <V> 泛型父类
|
||||
* @return 泛化集合
|
||||
* @since 5.8.1
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <K, V> Map<K, V> castUp(Map<? extends K, ? extends V> map) {
|
||||
return (Map<K, V>) map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 泛型集合向下转型。例如将Map<Number,Number>转换为Map<Integer, Integer>
|
||||
*
|
||||
* @param map 集合
|
||||
* @param <K> 泛型子类
|
||||
* @param <V> 泛型子类
|
||||
* @return 泛化集合
|
||||
* @since 5.8.1
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <K, V> Map<K, V> castDown(Map<? super K, ? super V> map) {
|
||||
return (Map<K, V>) map;
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package cn.hutool.core.exceptions;
|
||||
|
||||
/**
|
||||
* InvocationTargetException的运行时异常
|
||||
*
|
||||
* @author looly
|
||||
* @since 5.8.1
|
||||
*/
|
||||
public class InvocationTargetRuntimeException extends UtilException {
|
||||
|
||||
public InvocationTargetRuntimeException(Throwable e) {
|
||||
super(e);
|
||||
}
|
||||
|
||||
public InvocationTargetRuntimeException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public InvocationTargetRuntimeException(String messageTemplate, Object... params) {
|
||||
super(messageTemplate, params);
|
||||
}
|
||||
|
||||
public InvocationTargetRuntimeException(String message, Throwable throwable) {
|
||||
super(message, throwable);
|
||||
}
|
||||
|
||||
public InvocationTargetRuntimeException(String message, Throwable throwable, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, throwable, enableSuppression, writableStackTrace);
|
||||
}
|
||||
|
||||
public InvocationTargetRuntimeException(Throwable throwable, String messageTemplate, Object... params) {
|
||||
super(throwable, messageTemplate, params);
|
||||
}
|
||||
}
|
@ -1097,7 +1097,7 @@ public class FileUtil extends PathUtil {
|
||||
* 情况如下:
|
||||
*
|
||||
* <pre>
|
||||
* 1、src和dest都为目录,则讲src下所有文件目录拷贝到dest下
|
||||
* 1、src和dest都为目录,则将src下所有文件目录拷贝到dest下
|
||||
* 2、src和dest都为文件,直接复制,名字为dest
|
||||
* 3、src为文件,dest为目录,将src拷贝到dest目录下
|
||||
* </pre>
|
||||
@ -1117,7 +1117,7 @@ public class FileUtil extends PathUtil {
|
||||
* 情况如下:
|
||||
*
|
||||
* <pre>
|
||||
* 1、src和dest都为目录,则讲src下所有文件(包括子目录)拷贝到dest下
|
||||
* 1、src和dest都为目录,则将src下所有文件(包括子目录)拷贝到dest下
|
||||
* 2、src和dest都为文件,直接复制,名字为dest
|
||||
* 3、src为文件,dest为目录,将src拷贝到dest目录下
|
||||
* </pre>
|
||||
|
@ -6,6 +6,7 @@ import cn.hutool.core.lang.Editor;
|
||||
import cn.hutool.core.lang.Filter;
|
||||
import cn.hutool.core.lang.Pair;
|
||||
import cn.hutool.core.lang.TypeReference;
|
||||
import cn.hutool.core.stream.CollectorUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
@ -27,7 +28,6 @@ import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
/**
|
||||
@ -708,7 +708,7 @@ public class MapUtil {
|
||||
if (null == map || null == biFunction) {
|
||||
return MapUtil.newHashMap();
|
||||
}
|
||||
return map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, m -> biFunction.apply(m.getKey(), m.getValue())));
|
||||
return map.entrySet().stream().collect(CollectorUtil.toMap(Map.Entry::getKey, m -> biFunction.apply(m.getKey(), m.getValue()),(l,r)->l));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1432,7 +1432,7 @@ public class MapUtil {
|
||||
*/
|
||||
public static <K, V> Map.Entry<K, V> entry(K key, V value, boolean isImmutable) {
|
||||
return isImmutable ?
|
||||
new AbstractMap.SimpleEntry<>(key, value) :
|
||||
new AbstractMap.SimpleImmutableEntry<>(key, value);
|
||||
new AbstractMap.SimpleImmutableEntry<>(key, value) :
|
||||
new AbstractMap.SimpleEntry<>(key, value);
|
||||
}
|
||||
}
|
||||
|
@ -780,6 +780,28 @@ public class CharSequenceUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 给定字符串是否以任何一个字符串结尾(忽略大小写)<br>
|
||||
* 给定字符串和数组为空都返回false
|
||||
*
|
||||
* @param str 给定字符串
|
||||
* @param suffixes 需要检测的结尾字符串
|
||||
* @return 给定字符串是否以任何一个字符串结尾
|
||||
* @since 5.8.1
|
||||
*/
|
||||
public static boolean startWithAnyIgnoreCase(final CharSequence str, final CharSequence... suffixes) {
|
||||
if (isEmpty(str) || ArrayUtil.isEmpty(suffixes)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (final CharSequence suffix : suffixes) {
|
||||
if (startWith(str, suffix, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------ endWith
|
||||
|
||||
/**
|
||||
@ -2707,7 +2729,7 @@ public class CharSequenceUtil {
|
||||
* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
|
||||
* 例:<br>
|
||||
* 通常使用:format("this is {} for {}", "a", "b") =》 this is a for b<br>
|
||||
* 转义{}: format("this is \\{} for {}", "a", "b") =》 this is \{} for a<br>
|
||||
* 转义{}: format("this is \\{} for {}", "a", "b") =》 this is {} for a<br>
|
||||
* 转义\: format("this is \\\\{} for {}", "a", "b") =》 this is \a for b<br>
|
||||
*
|
||||
* @param template 文本模板,被替换的部分用 {} 表示,如果模板为null,返回"null"
|
||||
|
@ -15,6 +15,8 @@ public class BooleanUtil {
|
||||
|
||||
/** 表示为真的字符串 */
|
||||
private static final Set<String> TRUE_SET = CollUtil.newHashSet("true", "yes", "y", "t", "ok", "1", "on", "是", "对", "真", "對", "√");
|
||||
/** 表示为假的字符串 */
|
||||
private static final Set<String> FALSE_SET = CollUtil.newHashSet("false", "no", "n", "f", "0", "off", "否", "错", "假", "錯", "×");
|
||||
|
||||
/**
|
||||
* 取相反值
|
||||
@ -85,6 +87,28 @@ public class BooleanUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换字符串为boolean值<br>
|
||||
* 如果为["true", "yes", "y", "t", "ok", "1", "on", "是", "对", "真", "對", "√"],返回{@code true}<br>
|
||||
* 如果为["false", "no", "n", "f", "0", "off", "否", "错", "假", "錯", "×"],返回{@code false}<br>
|
||||
* 其他情况返回{@code null}
|
||||
*
|
||||
* @param valueStr 字符串
|
||||
* @return boolean值
|
||||
* @since 5.8.1
|
||||
*/
|
||||
public static Boolean toBooleanObject(String valueStr) {
|
||||
if (StrUtil.isNotBlank(valueStr)) {
|
||||
valueStr = valueStr.trim().toLowerCase();
|
||||
if(TRUE_SET.contains(valueStr)){
|
||||
return true;
|
||||
} else if(FALSE_SET.contains(valueStr)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* boolean值转为int
|
||||
*
|
||||
|
@ -74,12 +74,25 @@ public class ByteUtil {
|
||||
* @param byteOrder 端序
|
||||
* @return short值
|
||||
*/
|
||||
public static short bytesToShort(byte[] bytes, ByteOrder byteOrder) {
|
||||
public static short bytesToShort(final byte[] bytes, final ByteOrder byteOrder) {
|
||||
return bytesToShort(bytes, 0, byteOrder);
|
||||
}
|
||||
|
||||
/**
|
||||
* byte数组转short<br>
|
||||
* 自定义端序
|
||||
*
|
||||
* @param bytes byte数组,长度必须大于2
|
||||
* @param start 开始位置
|
||||
* @param byteOrder 端序
|
||||
* @return short值
|
||||
*/
|
||||
public static short bytesToShort(final byte[] bytes, final int start, final ByteOrder byteOrder) {
|
||||
if (ByteOrder.LITTLE_ENDIAN == byteOrder) {
|
||||
//小端模式,数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中
|
||||
return (short) (bytes[0] & 0xff | (bytes[1] & 0xff) << Byte.SIZE);
|
||||
return (short) (bytes[start] & 0xff | (bytes[start + 1] & 0xff) << Byte.SIZE);
|
||||
} else {
|
||||
return (short) (bytes[1] & 0xff | (bytes[0] & 0xff) << Byte.SIZE);
|
||||
return (short) (bytes[start + 1] & 0xff | (bytes[start] & 0xff) << Byte.SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2524,6 +2524,11 @@ public class NumberUtil {
|
||||
* @since 4.1.15
|
||||
*/
|
||||
public static Number parseNumber(String numberStr) throws NumberFormatException {
|
||||
if(StrUtil.startWithIgnoreCase(numberStr, "0x")){
|
||||
// 0x04表示16进制数
|
||||
return Long.parseLong(numberStr.substring(2), 16);
|
||||
}
|
||||
|
||||
try {
|
||||
final NumberFormat format = NumberFormat.getInstance();
|
||||
if (format instanceof DecimalFormat) {
|
||||
|
@ -5,6 +5,7 @@ import cn.hutool.core.bean.NullWrapperBean;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.UniqueKeySet;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.exceptions.InvocationTargetRuntimeException;
|
||||
import cn.hutool.core.exceptions.UtilException;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.lang.Filter;
|
||||
@ -16,6 +17,7 @@ import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
@ -864,7 +866,7 @@ public class ReflectUtil {
|
||||
* Set -》 HashSet
|
||||
* </pre>
|
||||
*
|
||||
* @param <T> 对象类型
|
||||
* @param <T> 对象类型
|
||||
* @param type 被构造的类
|
||||
* @return 构造后的对象,构造失败返回{@code null}
|
||||
*/
|
||||
@ -873,7 +875,7 @@ public class ReflectUtil {
|
||||
Assert.notNull(type);
|
||||
|
||||
// 原始类型
|
||||
if(type.isPrimitive()){
|
||||
if (type.isPrimitive()) {
|
||||
return (T) ClassUtil.getPrimitiveDefaultValue(type);
|
||||
}
|
||||
|
||||
@ -985,10 +987,42 @@ public class ReflectUtil {
|
||||
* @param method 方法(对象方法或static方法都可)
|
||||
* @param args 参数对象
|
||||
* @return 结果
|
||||
* @throws UtilException 一些列异常的包装
|
||||
* @throws InvocationTargetRuntimeException 目标方法执行异常
|
||||
* @throws UtilException {@link IllegalAccessException}异常的包装
|
||||
*/
|
||||
public static <T> T invoke(Object obj, Method method, Object... args) throws InvocationTargetRuntimeException, UtilException {
|
||||
try {
|
||||
return invokeRaw(obj, method, args);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new InvocationTargetRuntimeException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new UtilException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行方法
|
||||
*
|
||||
* <p>
|
||||
* 对于用户传入参数会做必要检查,包括:
|
||||
*
|
||||
* <pre>
|
||||
* 1、忽略多余的参数
|
||||
* 2、参数不够补齐默认值
|
||||
* 3、传入参数为null,但是目标参数类型为原始类型,做转换
|
||||
* </pre>
|
||||
*
|
||||
* @param <T> 返回对象类型
|
||||
* @param obj 对象,如果执行静态方法,此值为{@code null}
|
||||
* @param method 方法(对象方法或static方法都可)
|
||||
* @param args 参数对象
|
||||
* @return 结果
|
||||
* @throws InvocationTargetRuntimeException 目标方法执行异常
|
||||
* @throws UtilException {@link IllegalAccessException}异常的包装
|
||||
* @since 5.8.1
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T invoke(Object obj, Method method, Object... args) throws UtilException {
|
||||
public static <T> T invokeRaw(Object obj, Method method, Object... args) throws InvocationTargetException, IllegalAccessException {
|
||||
setAccessible(method);
|
||||
|
||||
// 检查用户传入参数:
|
||||
@ -1025,11 +1059,7 @@ public class ReflectUtil {
|
||||
return MethodHandleUtil.invokeSpecial(obj, method, args);
|
||||
}
|
||||
|
||||
try {
|
||||
return (T) method.invoke(ClassUtil.isStatic(method) ? null : obj, actualArgs);
|
||||
} catch (Exception e) {
|
||||
throw new UtilException(e);
|
||||
}
|
||||
return (T) method.invoke(ClassUtil.isStatic(method) ? null : obj, actualArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1041,7 +1071,7 @@ public class ReflectUtil {
|
||||
* @param methodName 方法名
|
||||
* @param args 参数列表
|
||||
* @return 执行结果
|
||||
* @throws UtilException IllegalAccessException包装
|
||||
* @throws UtilException IllegalAccessException等异常包装
|
||||
* @see NullWrapperBean
|
||||
* @since 3.1.2
|
||||
*/
|
||||
|
@ -191,6 +191,23 @@ public class BeanUtilTest {
|
||||
Assert.assertFalse(map.containsKey("SUBNAME"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void beanToMapNullPropertiesTest() {
|
||||
SubPerson person = new SubPerson();
|
||||
person.setAge(14);
|
||||
person.setOpenid("11213232");
|
||||
person.setName("测试A11");
|
||||
person.setSubName("sub名字");
|
||||
|
||||
Map<String, Object> map = BeanUtil.beanToMap(person, null);
|
||||
|
||||
Assert.assertEquals("测试A11", map.get("name"));
|
||||
Assert.assertEquals(14, map.get("age"));
|
||||
Assert.assertEquals("11213232", map.get("openid"));
|
||||
// static属性应被忽略
|
||||
Assert.assertFalse(map.containsKey("SUBNAME"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void beanToMapTest2() {
|
||||
SubPerson person = new SubPerson();
|
||||
|
@ -0,0 +1,45 @@
|
||||
package cn.hutool.core.convert;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class CastUtilTest {
|
||||
|
||||
@Test
|
||||
public void testCastToSuper() {
|
||||
Collection<Integer> collection= CollUtil.newLinkedList(1,2,3);
|
||||
List<Integer> list = CollUtil.newArrayList(1, 2, 3);
|
||||
Set<Integer> set = CollUtil.newHashSet(1, 2, 3);
|
||||
Map<Integer, Integer> map = new HashMap<>();
|
||||
map.put(1, 1);
|
||||
|
||||
Collection<Number> collection2 = CastUtil.castUp(collection);
|
||||
Assert.assertSame(collection, collection2);
|
||||
|
||||
Collection<Integer> collection3 = CastUtil.castDown(collection2);
|
||||
Assert.assertSame(collection2, collection3);
|
||||
|
||||
List<Number> list2 = CastUtil.castUp(list);
|
||||
Assert.assertSame(list, list2);
|
||||
List<Integer> list3 = CastUtil.castDown(list2);
|
||||
Assert.assertSame(list2, list3);
|
||||
|
||||
Set<Number> set2 = CastUtil.castUp(set);
|
||||
Assert.assertSame(set, set2);
|
||||
Set<Integer> set3 = CastUtil.castDown(set2);
|
||||
Assert.assertSame(set2, set3);
|
||||
|
||||
Map<Number, Serializable> map2 = CastUtil.castUp(map);
|
||||
Assert.assertSame(map, map2);
|
||||
Map<Integer, Number> map3 = CastUtil.castDown(map2);
|
||||
Assert.assertSame(map2, map3);
|
||||
}
|
||||
}
|
@ -82,7 +82,8 @@ public class MapUtilTest {
|
||||
// 如你所见,它是一个map,key由用户id,value由用户组成
|
||||
Map<Long, User> idUserMap = Stream.iterate(0L, i -> ++i).limit(4).map(i -> User.builder().id(i).name(customers.poll()).build()).collect(Collectors.toMap(User::getId, Function.identity()));
|
||||
// 如你所见,它是一个map,key由分组id,value由用户ids组成,典型的多对多关系
|
||||
Map<Long, List<Long>> groupIdUserIdsMap = groups.stream().flatMap(group -> idUserMap.keySet().stream().map(userId -> UserGroup.builder().groupId(group.getId()).userId(userId).build())).collect(Collectors.groupingBy(UserGroup::getUserId, Collectors.mapping(UserGroup::getGroupId, Collectors.toList())));
|
||||
Map<Long, List<Long>> groupIdUserIdsMap = groups.stream().flatMap(group -> idUserMap.keySet().stream().map(userId -> UserGroup.builder().groupId(group.getId()).userId(userId).build()))
|
||||
.collect(Collectors.groupingBy(UserGroup::getGroupId, Collectors.mapping(UserGroup::getUserId, Collectors.toList())));
|
||||
|
||||
// 神奇的魔法发生了, 分组id和用户ids组成的map,竟然变成了订单编号和用户实体集合组成的map
|
||||
Map<Long, List<User>> groupIdUserMap = MapUtil.map(groupIdUserIdsMap, (groupId, userIds) -> userIds.stream().map(idUserMap::get).collect(Collectors.toList()));
|
||||
@ -98,7 +99,8 @@ public class MapUtilTest {
|
||||
Assert.assertEquals("竹鼠发烧找华农", users.get(2).getName());
|
||||
Assert.assertEquals("朴实无华朱一旦", users.get(3).getName());
|
||||
});
|
||||
// 能写代码真开心
|
||||
// 对null友好
|
||||
MapUtil.map(MapUtil.of(0, 0), (k, v) -> null).forEach((k, v) -> Assert.assertNull(v));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -292,6 +292,13 @@ public class NumberUtilTest {
|
||||
Assert.assertEquals(1482L, v2.longValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseHexNumberTest() {
|
||||
// 千位分隔符去掉
|
||||
final int v1 = NumberUtil.parseNumber("0xff").intValue();
|
||||
Assert.assertEquals(255, v1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseLongTest() {
|
||||
long number = NumberUtil.parseLong("0xFF");
|
||||
|
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hutool-cron</artifactId>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hutool-crypto</artifactId>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hutool-db</artifactId>
|
||||
@ -81,7 +81,7 @@
|
||||
<dependency>
|
||||
<groupId>com.github.chris2018998</groupId>
|
||||
<artifactId>beecp</artifactId>
|
||||
<version>3.3.5</version>
|
||||
<version>3.3.6</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
|
@ -9,7 +9,7 @@ import cn.hutool.core.util.StrUtil;
|
||||
* @author Looly
|
||||
*/
|
||||
public enum DialectName {
|
||||
ANSI, MYSQL, ORACLE, POSTGREESQL, SQLITE3, H2, SQLSERVER, SQLSERVER2012, PHOENIX;
|
||||
ANSI, MYSQL, ORACLE, POSTGRESQL, SQLITE3, H2, SQLSERVER, SQLSERVER2012, PHOENIX;
|
||||
|
||||
/**
|
||||
* 是否为指定数据库方言,检查时不分区大小写
|
||||
|
@ -28,7 +28,7 @@ public class PostgresqlDialect extends AnsiSqlDialect{
|
||||
|
||||
@Override
|
||||
public String dialectName() {
|
||||
return DialectName.POSTGREESQL.name();
|
||||
return DialectName.POSTGRESQL.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hutool-dfa</artifactId>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hutool-extra</artifactId>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hutool-http</artifactId>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hutool-json</artifactId>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hutool-jwt</artifactId>
|
||||
|
@ -222,7 +222,9 @@ public class JWTValidator {
|
||||
if (null == dateToCheck) {
|
||||
return;
|
||||
}
|
||||
now.setTime(now.getTime() + leeway * 1000);
|
||||
if(leeway > 0){
|
||||
now = DateUtil.date(now.getTime() + leeway * 1000);
|
||||
}
|
||||
if (dateToCheck.after(now)) {
|
||||
throw new ValidateException("'{}':[{}] is after now:[{}]",
|
||||
fieldName, DateUtil.date(dateToCheck), DateUtil.date(now));
|
||||
@ -244,7 +246,9 @@ public class JWTValidator {
|
||||
if (null == dateToCheck) {
|
||||
return;
|
||||
}
|
||||
now.setTime(now.getTime() - leeway * 1000);
|
||||
if(leeway > 0){
|
||||
now = DateUtil.date(now.getTime() - leeway * 1000);
|
||||
}
|
||||
if (dateToCheck.before(now)) {
|
||||
throw new ValidateException("'{}':[{}] is before now:[{}]",
|
||||
fieldName, DateUtil.date(dateToCheck), DateUtil.date(now));
|
||||
|
@ -6,6 +6,8 @@ import cn.hutool.jwt.signers.JWTSignerUtil;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class JWTValidatorTest {
|
||||
|
||||
@Test(expected = ValidateException.class)
|
||||
@ -79,4 +81,20 @@ public class JWTValidatorTest {
|
||||
|
||||
JWTValidator.of(jwt).validateDate(DateUtil.date());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void issue2329Test(){
|
||||
final long NOW = System.currentTimeMillis();
|
||||
final Date NOW_TIME = new Date(NOW);
|
||||
final long EXPIRED = 3 * 1000L;
|
||||
final Date EXPIRED_TIME = new Date(NOW + EXPIRED);
|
||||
|
||||
// 使用这种方式生成token
|
||||
final String token = JWT.create().setPayload("sub", "blue-light").setIssuedAt(NOW_TIME).setNotBefore(EXPIRED_TIME)
|
||||
.setExpiresAt(EXPIRED_TIME).setKey("123456".getBytes()).sign();
|
||||
|
||||
// 使用这种方式验证token
|
||||
JWTValidator.of(JWT.of(token)).validateDate(DateUtil.date(NOW - 4000), 10);
|
||||
JWTValidator.of(JWT.of(token)).validateDate(DateUtil.date(NOW + 4000), 10);
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hutool-log</artifactId>
|
||||
@ -24,6 +24,7 @@
|
||||
<log4j2.version>2.17.2</log4j2.version>
|
||||
<commons-logging.version>1.2</commons-logging.version>
|
||||
<tinylog.version>1.3.6</tinylog.version>
|
||||
<!-- 此处固定3.4.x,支持到jdk8 -->
|
||||
<jboss-logging.version>3.4.3.Final</jboss-logging.version>
|
||||
<logtube.version>0.43.2</logtube.version>
|
||||
</properties>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hutool-poi</artifactId>
|
||||
@ -45,7 +45,7 @@
|
||||
<dependency>
|
||||
<groupId>org.ofdrw</groupId>
|
||||
<artifactId>ofdrw-full</artifactId>
|
||||
<version>1.17.14</version>
|
||||
<version>1.17.15</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hutool-script</artifactId>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hutool-setting</artifactId>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hutool-socket</artifactId>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hutool-system</artifactId>
|
||||
|
@ -30,14 +30,21 @@ public class JavaInfo implements Serializable {
|
||||
private final boolean IS_JAVA_10 = getJavaVersionMatches("10");
|
||||
private final boolean IS_JAVA_11 = getJavaVersionMatches("11");
|
||||
private final boolean IS_JAVA_12 = getJavaVersionMatches("12");
|
||||
private final boolean IS_JAVA_13 = getJavaVersionMatches("13");
|
||||
private final boolean IS_JAVA_14 = getJavaVersionMatches("14");
|
||||
private final boolean IS_JAVA_15 = getJavaVersionMatches("15");
|
||||
private final boolean IS_JAVA_16 = getJavaVersionMatches("16");
|
||||
private final boolean IS_JAVA_17 = getJavaVersionMatches("17");
|
||||
private final boolean IS_JAVA_18 = getJavaVersionMatches("18");
|
||||
|
||||
|
||||
/**
|
||||
* 取得当前Java impl.的版本(取自系统属性:<code>java.version</code>)。
|
||||
* 取得当前Java impl.的版本(取自系统属性:{@code java.version})。
|
||||
*
|
||||
* <p>
|
||||
* 例如Sun JDK 1.4.2:<code>"1.4.2"</code>
|
||||
* 例如Sun JDK 1.4.2:{@code "1.4.2"}
|
||||
*
|
||||
* @return 属性值,如果不能取得(因为Java安全限制)或值不存在,则返回<code>null</code>。
|
||||
* @return 属性值,如果不能取得(因为Java安全限制)或值不存在,则返回{@code null}。
|
||||
* @since Java 1.1
|
||||
*/
|
||||
public final String getVersion() {
|
||||
@ -45,35 +52,35 @@ public class JavaInfo implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得当前Java impl.的版本(取自系统属性:<code>java.version</code>)。
|
||||
* 取得当前Java impl.的版本(取自系统属性:{@code java.version})。
|
||||
*
|
||||
* <p>
|
||||
* 例如:
|
||||
*
|
||||
* <ul>
|
||||
* <li>JDK 1.2:<code>1.2f</code>。</li>
|
||||
* <li>JDK 1.3.1:<code>1.31f</code></li>
|
||||
* <li>JDK 1.2:{@code 1.2f}。</li>
|
||||
* <li>JDK 1.3.1:{@code 1.31f}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @return 属性值,如果不能取得(因为Java安全限制)或值不存在,则返回<code>0</code>。
|
||||
* @return 属性值,如果不能取得(因为Java安全限制)或值不存在,则返回{@code 0}。
|
||||
*/
|
||||
public final float getVersionFloat() {
|
||||
return JAVA_VERSION_FLOAT;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得当前Java impl.的版本(取自系统属性:<code>java.version</code>),java10及其之后的版本返回值为4位。
|
||||
* 取得当前Java impl.的版本(取自系统属性:{@code java.version}),java10及其之后的版本返回值为4位。
|
||||
*
|
||||
* <p>
|
||||
* 例如:
|
||||
*
|
||||
* <ul>
|
||||
* <li>JDK 1.2:<code>120</code>。</li>
|
||||
* <li>JDK 1.3.1:<code>131</code></li>
|
||||
* <li>JDK 11.0.2:<code>1102</code></li>
|
||||
* <li>JDK 1.2:{@code 120}。</li>
|
||||
* <li>JDK 1.3.1:{@code 131}</li>
|
||||
* <li>JDK 11.0.2:{@code 1102}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @return 属性值,如果不能取得(因为Java安全限制)或值不存在,则返回<code>0</code>。
|
||||
* @return 属性值,如果不能取得(因为Java安全限制)或值不存在,则返回{@code 0}。
|
||||
* @since Java 1.1
|
||||
*/
|
||||
public final int getVersionInt() {
|
||||
@ -81,9 +88,9 @@ public class JavaInfo implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得当前Java impl.的版本的<code>float</code>值。
|
||||
* 取得当前Java impl.的版本的{@code float}值。
|
||||
*
|
||||
* @return Java版本的<code>float</code>值或<code>0</code>
|
||||
* @return Java版本的<code>float</code>值或{@code 0}
|
||||
*/
|
||||
private float getJavaVersionAsFloat() {
|
||||
if (JAVA_VERSION == null) {
|
||||
@ -98,18 +105,18 @@ public class JavaInfo implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得当前Java impl.的版本的<code>int</code>值。
|
||||
* 取得当前Java impl.的版本的{@code int}值。
|
||||
*
|
||||
* @return Java版本的<code>int</code>值或<code>0</code>
|
||||
* @return Java版本的<code>int</code>值或{@code 0}
|
||||
*/
|
||||
private int getJavaVersionAsInt() {
|
||||
if (JAVA_VERSION == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
String javaVersion = ReUtil.get("^[0-9]{1,2}(\\.[0-9]{1,2}){0,2}", JAVA_VERSION, 0);
|
||||
final String javaVersion = ReUtil.get("^[0-9]{1,2}(\\.[0-9]{1,2}){0,2}", JAVA_VERSION, 0);
|
||||
|
||||
String[] split = javaVersion.split("\\.");
|
||||
final String[] split = javaVersion.split("\\.");
|
||||
String result = ArrayUtil.join(split, "");
|
||||
|
||||
//保证java10及其之后的版本返回的值为4位
|
||||
@ -121,12 +128,12 @@ public class JavaInfo implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得当前Java impl.的厂商(取自系统属性:<code>java.vendor</code>)。
|
||||
* 取得当前Java impl.的厂商(取自系统属性:{@code java.vendor})。
|
||||
*
|
||||
* <p>
|
||||
* 例如Sun JDK 1.4.2:<code>"Sun Microsystems Inc."</code>
|
||||
* 例如Sun JDK 1.4.2:{@code "Sun Microsystems Inc."}
|
||||
*
|
||||
* @return 属性值,如果不能取得(因为Java安全限制)或值不存在,则返回<code>null</code>。
|
||||
* @return 属性值,如果不能取得(因为Java安全限制)或值不存在,则返回{@code null}。
|
||||
* @since Java 1.1
|
||||
*/
|
||||
public final String getVendor() {
|
||||
@ -134,12 +141,12 @@ public class JavaInfo implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得当前Java impl.的厂商网站的URL(取自系统属性:<code>java.vendor.url</code>)。
|
||||
* 取得当前Java impl.的厂商网站的URL(取自系统属性:{@code java.vendor.url})。
|
||||
*
|
||||
* <p>
|
||||
* 例如Sun JDK 1.4.2:<code>"http://java.sun.com/"</code>
|
||||
* 例如Sun JDK 1.4.2:{@code "<a href="http://java.sun.com/">http://java.sun.com/</a>"}
|
||||
*
|
||||
* @return 属性值,如果不能取得(因为Java安全限制)或值不存在,则返回<code>null</code>。
|
||||
* @return 属性值,如果不能取得(因为Java安全限制)或值不存在,则返回{@code null}。
|
||||
* @since Java 1.1
|
||||
*/
|
||||
public final String getVendorURL() {
|
||||
@ -150,9 +157,9 @@ public class JavaInfo implements Serializable {
|
||||
* 判断当前Java的版本。
|
||||
*
|
||||
* <p>
|
||||
* 如果不能取得系统属性<code>java.version</code>(因为Java安全限制),则总是返回 <code>false</code>
|
||||
* 如果不能取得系统属性{@code java.version}(因为Java安全限制),则总是返回 {@code false}
|
||||
*
|
||||
* @return 如果当前Java版本为1.1,则返回<code>true</code>
|
||||
* @return 如果当前Java版本为1.1,则返回{@code true}
|
||||
*/
|
||||
public final boolean isJava1_1() {
|
||||
return IS_JAVA_1_1;
|
||||
@ -162,9 +169,9 @@ public class JavaInfo implements Serializable {
|
||||
* 判断当前Java的版本。
|
||||
*
|
||||
* <p>
|
||||
* 如果不能取得系统属性<code>java.version</code>(因为Java安全限制),则总是返回 <code>false</code>
|
||||
* 如果不能取得系统属性{@code java.version}(因为Java安全限制),则总是返回 {@code false}
|
||||
*
|
||||
* @return 如果当前Java版本为1.2,则返回<code>true</code>
|
||||
* @return 如果当前Java版本为1.2,则返回{@code true}
|
||||
*/
|
||||
public final boolean isJava1_2() {
|
||||
return IS_JAVA_1_2;
|
||||
@ -174,9 +181,9 @@ public class JavaInfo implements Serializable {
|
||||
* 判断当前Java的版本。
|
||||
*
|
||||
* <p>
|
||||
* 如果不能取得系统属性<code>java.version</code>(因为Java安全限制),则总是返回 <code>false</code>
|
||||
* 如果不能取得系统属性{@code java.version}(因为Java安全限制),则总是返回 {@code false}
|
||||
*
|
||||
* @return 如果当前Java版本为1.3,则返回<code>true</code>
|
||||
* @return 如果当前Java版本为1.3,则返回{@code true}
|
||||
*/
|
||||
public final boolean isJava1_3() {
|
||||
return IS_JAVA_1_3;
|
||||
@ -186,9 +193,9 @@ public class JavaInfo implements Serializable {
|
||||
* 判断当前Java的版本。
|
||||
*
|
||||
* <p>
|
||||
* 如果不能取得系统属性<code>java.version</code>(因为Java安全限制),则总是返回 <code>false</code>
|
||||
* 如果不能取得系统属性{@code java.version}(因为Java安全限制),则总是返回 {@code false}
|
||||
*
|
||||
* @return 如果当前Java版本为1.4,则返回<code>true</code>
|
||||
* @return 如果当前Java版本为1.4,则返回{@code true}
|
||||
*/
|
||||
public final boolean isJava1_4() {
|
||||
return IS_JAVA_1_4;
|
||||
@ -198,9 +205,9 @@ public class JavaInfo implements Serializable {
|
||||
* 判断当前Java的版本。
|
||||
*
|
||||
* <p>
|
||||
* 如果不能取得系统属性<code>java.version</code>(因为Java安全限制),则总是返回 <code>false</code>
|
||||
* 如果不能取得系统属性{@code java.version}(因为Java安全限制),则总是返回 {@code false}
|
||||
*
|
||||
* @return 如果当前Java版本为1.5,则返回<code>true</code>
|
||||
* @return 如果当前Java版本为1.5,则返回{@code true}
|
||||
*/
|
||||
public final boolean isJava1_5() {
|
||||
return IS_JAVA_1_5;
|
||||
@ -210,9 +217,9 @@ public class JavaInfo implements Serializable {
|
||||
* 判断当前Java的版本。
|
||||
*
|
||||
* <p>
|
||||
* 如果不能取得系统属性<code>java.version</code>(因为Java安全限制),则总是返回 <code>false</code>
|
||||
* 如果不能取得系统属性{@code java.version}(因为Java安全限制),则总是返回 {@code false}
|
||||
*
|
||||
* @return 如果当前Java版本为1.6,则返回<code>true</code>
|
||||
* @return 如果当前Java版本为1.6,则返回{@code true}
|
||||
*/
|
||||
public final boolean isJava1_6() {
|
||||
return IS_JAVA_1_6;
|
||||
@ -222,9 +229,9 @@ public class JavaInfo implements Serializable {
|
||||
* 判断当前Java的版本。
|
||||
*
|
||||
* <p>
|
||||
* 如果不能取得系统属性<code>java.version</code>(因为Java安全限制),则总是返回 <code>false</code>
|
||||
* 如果不能取得系统属性{@code java.version}(因为Java安全限制),则总是返回 {@code false}
|
||||
*
|
||||
* @return 如果当前Java版本为1.7,则返回<code>true</code>
|
||||
* @return 如果当前Java版本为1.7,则返回{@code true}
|
||||
*/
|
||||
public final boolean isJava1_7() {
|
||||
return IS_JAVA_1_7;
|
||||
@ -234,9 +241,9 @@ public class JavaInfo implements Serializable {
|
||||
* 判断当前Java的版本。
|
||||
*
|
||||
* <p>
|
||||
* 如果不能取得系统属性<code>java.version</code>(因为Java安全限制),则总是返回 <code>false</code>
|
||||
* 如果不能取得系统属性{@code java.version}(因为Java安全限制),则总是返回 {@code false}
|
||||
*
|
||||
* @return 如果当前Java版本为1.8,则返回<code>true</code>
|
||||
* @return 如果当前Java版本为1.8,则返回{@code true}
|
||||
*/
|
||||
public final boolean isJava1_8() {
|
||||
return IS_JAVA_1_8;
|
||||
@ -246,9 +253,9 @@ public class JavaInfo implements Serializable {
|
||||
* 判断当前Java的版本。
|
||||
*
|
||||
* <p>
|
||||
* 如果不能取得系统属性<code>java.version</code>(因为Java安全限制),则总是返回 <code>false</code>
|
||||
* 如果不能取得系统属性{@code java.version}(因为Java安全限制),则总是返回 {@code false}
|
||||
*
|
||||
* @return 如果当前Java版本为9,则返回<code>true</code>
|
||||
* @return 如果当前Java版本为9,则返回{@code true}
|
||||
*/
|
||||
public final boolean isJava9() {
|
||||
return IS_JAVA_9;
|
||||
@ -258,9 +265,9 @@ public class JavaInfo implements Serializable {
|
||||
* 判断当前Java的版本。
|
||||
*
|
||||
* <p>
|
||||
* 如果不能取得系统属性<code>java.version</code>(因为Java安全限制),则总是返回 <code>false</code>
|
||||
* 如果不能取得系统属性{@code java.version}(因为Java安全限制),则总是返回 {@code false}
|
||||
*
|
||||
* @return 如果当前Java版本为10,则返回<code>true</code>
|
||||
* @return 如果当前Java版本为10,则返回{@code true}
|
||||
*/
|
||||
public final boolean isJava10() {
|
||||
return IS_JAVA_10;
|
||||
@ -270,9 +277,9 @@ public class JavaInfo implements Serializable {
|
||||
* 判断当前Java的版本。
|
||||
*
|
||||
* <p>
|
||||
* 如果不能取得系统属性<code>java.version</code>(因为Java安全限制),则总是返回 <code>false</code>
|
||||
* 如果不能取得系统属性{@code java.version}(因为Java安全限制),则总是返回 {@code false}
|
||||
*
|
||||
* @return 如果当前Java版本为11,则返回<code>true</code>
|
||||
* @return 如果当前Java版本为11,则返回{@code true}
|
||||
*/
|
||||
public final boolean isJava11() {
|
||||
return IS_JAVA_11;
|
||||
@ -282,21 +289,94 @@ public class JavaInfo implements Serializable {
|
||||
* 判断当前Java的版本。
|
||||
*
|
||||
* <p>
|
||||
* 如果不能取得系统属性<code>java.version</code>(因为Java安全限制),则总是返回 <code>false</code>
|
||||
* 如果不能取得系统属性{@code java.version}(因为Java安全限制),则总是返回 {@code false}
|
||||
*
|
||||
* @return 如果当前Java版本为12,则返回<code>true</code>
|
||||
* @return 如果当前Java版本为12,则返回{@code true}
|
||||
*/
|
||||
public final boolean isJava12() {
|
||||
return IS_JAVA_12;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前Java的版本。
|
||||
*
|
||||
* <p>
|
||||
* 如果不能取得系统属性{@code java.version}(因为Java安全限制),则总是返回 {@code false}
|
||||
*
|
||||
* @return 如果当前Java版本为13,则返回{@code true}
|
||||
*/
|
||||
public final boolean isJava13() {
|
||||
return IS_JAVA_13;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断当前Java的版本。
|
||||
*
|
||||
* <p>
|
||||
* 如果不能取得系统属性{@code java.version}(因为Java安全限制),则总是返回 {@code false}
|
||||
*
|
||||
* @return 如果当前Java版本为14,则返回{@code true}
|
||||
*/
|
||||
public final boolean isJava14() {
|
||||
return IS_JAVA_14;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前Java的版本。
|
||||
*
|
||||
* <p>
|
||||
* 如果不能取得系统属性{@code java.version}(因为Java安全限制),则总是返回 {@code false}
|
||||
*
|
||||
* @return 如果当前Java版本为15,则返回{@code true}
|
||||
*/
|
||||
public final boolean isJava15() {
|
||||
return IS_JAVA_15;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前Java的版本。
|
||||
*
|
||||
* <p>
|
||||
* 如果不能取得系统属性{@code java.version}(因为Java安全限制),则总是返回 {@code false}
|
||||
*
|
||||
* @return 如果当前Java版本为16,则返回{@code true}
|
||||
*/
|
||||
public final boolean isJava16() {
|
||||
return IS_JAVA_16;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前Java的版本。
|
||||
*
|
||||
* <p>
|
||||
* 如果不能取得系统属性{@code java.version}(因为Java安全限制),则总是返回 {@code false}
|
||||
*
|
||||
* @return 如果当前Java版本为17,则返回{@code true}
|
||||
*/
|
||||
public final boolean isJava17() {
|
||||
return IS_JAVA_17;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前Java的版本。
|
||||
*
|
||||
* <p>
|
||||
* 如果不能取得系统属性{@code java.version}(因为Java安全限制),则总是返回 {@code false}
|
||||
*
|
||||
* @return 如果当前Java版本为18,则返回{@code true}
|
||||
*/
|
||||
public final boolean isJava18() {
|
||||
return IS_JAVA_18;
|
||||
}
|
||||
|
||||
/**
|
||||
* 匹配当前Java的版本。
|
||||
*
|
||||
* @param versionPrefix Java版本前缀
|
||||
* @return 如果版本匹配,则返回<code>true</code>
|
||||
* @return 如果版本匹配,则返回{@code true}
|
||||
*/
|
||||
private boolean getJavaVersionMatches(String versionPrefix) {
|
||||
private boolean getJavaVersionMatches(final String versionPrefix) {
|
||||
if (JAVA_VERSION == null) {
|
||||
return false;
|
||||
}
|
||||
@ -312,14 +392,14 @@ public class JavaInfo implements Serializable {
|
||||
*
|
||||
*
|
||||
* <ul>
|
||||
* <li>测试JDK 1.2:<code>isJavaVersionAtLeast(1.2f)</code></li>
|
||||
* <li>测试JDK 1.2.1:<code>isJavaVersionAtLeast(1.31f)</code></li>
|
||||
* <li>测试JDK 1.2:{@code isJavaVersionAtLeast(1.2f)}</li>
|
||||
* <li>测试JDK 1.2.1:{@code isJavaVersionAtLeast(1.31f)}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param requiredVersion 需要的版本
|
||||
* @return 如果当前Java版本大于或等于指定的版本,则返回<code>true</code>
|
||||
* @return 如果当前Java版本大于或等于指定的版本,则返回{@code true}
|
||||
*/
|
||||
public final boolean isJavaVersionAtLeast(float requiredVersion) {
|
||||
public final boolean isJavaVersionAtLeast(final float requiredVersion) {
|
||||
return getVersionFloat() >= requiredVersion;
|
||||
}
|
||||
|
||||
@ -331,14 +411,14 @@ public class JavaInfo implements Serializable {
|
||||
*
|
||||
*
|
||||
* <ul>
|
||||
* <li>测试JDK 1.2:<code>isJavaVersionAtLeast(120)</code></li>
|
||||
* <li>测试JDK 1.2.1:<code>isJavaVersionAtLeast(131)</code></li>
|
||||
* <li>测试JDK 1.2:{@code isJavaVersionAtLeast(120)}</li>
|
||||
* <li>测试JDK 1.2.1:{@code isJavaVersionAtLeast(131)}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param requiredVersion 需要的版本
|
||||
* @return 如果当前Java版本大于或等于指定的版本,则返回<code>true</code>
|
||||
* @return 如果当前Java版本大于或等于指定的版本,则返回{@code true}
|
||||
*/
|
||||
public final boolean isJavaVersionAtLeast(int requiredVersion) {
|
||||
public final boolean isJavaVersionAtLeast(final int requiredVersion) {
|
||||
return getVersionInt() >= requiredVersion;
|
||||
}
|
||||
|
||||
@ -349,7 +429,7 @@ public class JavaInfo implements Serializable {
|
||||
*/
|
||||
@Override
|
||||
public final String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
|
||||
SystemUtil.append(builder, "Java Version: ", getVersion());
|
||||
SystemUtil.append(builder, "Java Vendor: ", getVendor());
|
||||
|
2
pom.xml
2
pom.xml
@ -8,7 +8,7 @@
|
||||
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-parent</artifactId>
|
||||
<version>5.8.0</version>
|
||||
<version>5.8.1</version>
|
||||
<name>hutool</name>
|
||||
<description>Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。</description>
|
||||
<url>https://github.com/dromara/hutool</url>
|
||||
|
Loading…
Reference in New Issue
Block a user