Prepare release

This commit is contained in:
Looly 2022-05-16 19:08:00 +08:00
commit a0c65de743
48 changed files with 609 additions and 156 deletions

View File

@ -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 】 新增CastUtilpr#2313@Github
* 【core 】 ByteUtil新增bytesToShort重载issue#I57FA7@Gitee
* 【core 】 ReflectUtil.invoke方法抛出运行时异常增加InvocationTargetRuntimeExceptionissue#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中修正为POSTGRESQLissue#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)

View File

@ -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.

View File

@ -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平台没有测试不能保证所有工具类或工具方法可用。

View File

@ -1 +1 @@
5.8.0
5.8.1

View File

@ -1 +1 @@
var version = '5.8.0'
var version = '5.8.1'

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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 BeanMap或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
}

View File

@ -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);
}
/**

View File

@ -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
*/

View 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&lt;Integer&gt;转换为Collection&lt;Number&gt;
*
* @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&lt;Number&gt;转换为Collection&lt;Integer&gt;
*
* @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&lt;Integer&gt;转换为Set&lt;Number&gt;
*
* @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&lt;Number&gt;转换为Set&lt;Integer&gt;
*
* @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&lt;Integer&gt;转换为List&lt;Number&gt;
*
* @param list 集合
* @param <T> 泛型的父类
* @return 泛化集合
*/
@SuppressWarnings("unchecked")
public static <T> List<T> castUp(List<? extends T> list) {
return (List<T>) list;
}
/**
* 泛型集合向下转型例如将List&lt;Number&gt;转换为List&lt;Integer&gt;
*
* @param list 集合
* @param <T> 泛型的子类
* @return 泛化集合
*/
@SuppressWarnings("unchecked")
public static <T> List<T> castDown(List<? super T> list) {
return (List<T>) list;
}
/**
* 泛型集合向下转型例如将Map&lt;Integer, Integer&gt;转换为Map&lt;Number,Number&gt;
*
* @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&lt;Number,Number&gt;转换为Map&lt;Integer, Integer&gt;
*
* @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;
}
}

View File

@ -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);
}
}

View File

@ -1097,7 +1097,7 @@ public class FileUtil extends PathUtil {
* 情况如下
*
* <pre>
* 1src和dest都为目录src下所有文件目录拷贝到dest下
* 1src和dest都为目录src下所有文件目录拷贝到dest下
* 2src和dest都为文件直接复制名字为dest
* 3src为文件dest为目录将src拷贝到dest目录下
* </pre>
@ -1117,7 +1117,7 @@ public class FileUtil extends PathUtil {
* 情况如下
*
* <pre>
* 1src和dest都为目录src下所有文件包括子目录拷贝到dest下
* 1src和dest都为目录src下所有文件包括子目录拷贝到dest下
* 2src和dest都为文件直接复制名字为dest
* 3src为文件dest为目录将src拷贝到dest目录下
* </pre>

View File

@ -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);
}
}

View File

@ -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"

View File

@ -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
*

View File

@ -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);
}
}

View File

@ -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) {

View File

@ -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
*/

View File

@ -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();

View File

@ -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);
}
}

View File

@ -82,7 +82,8 @@ public class MapUtilTest {
// 如你所见它是一个mapkey由用户idvalue由用户组成
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()));
// 如你所见它是一个mapkey由分组idvalue由用户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

View File

@ -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");

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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;
/**
* 是否为指定数据库方言检查时不分区大小写

View File

@ -28,7 +28,7 @@ public class PostgresqlDialect extends AnsiSqlDialect{
@Override
public String dialectName() {
return DialectName.POSTGREESQL.name();
return DialectName.POSTGRESQL.name();
}
@Override

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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));

View File

@ -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);
}
}

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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());

View File

@ -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>