mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
fix code
This commit is contained in:
@@ -10,12 +10,7 @@ import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.CharUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Bean路径表达式,用于获取多层嵌套Bean中的字段值或Bean对象<br>
|
||||
@@ -119,11 +114,14 @@ public class BeanPath implements Serializable {
|
||||
public void set(final Object bean, final Object value) {
|
||||
Objects.requireNonNull(bean);
|
||||
|
||||
Object subBean = bean, previousBean;
|
||||
Object subBean = bean;
|
||||
Object previousBean = null;
|
||||
boolean isFirst = true;
|
||||
String patternPart;
|
||||
// 尝试找到倒数第二个子对象, 最终需要设置它的字段值
|
||||
final int length = patternParts.size() - 1;
|
||||
|
||||
// 填充父字段缺失的对象
|
||||
for (int i = 0; i < length; i++) {
|
||||
patternPart = patternParts.get(i);
|
||||
// 保存当前操作的bean, 以便subBean不存在时, 可以用来填充缺失的子对象
|
||||
@@ -145,8 +143,13 @@ public class BeanPath implements Serializable {
|
||||
}
|
||||
}
|
||||
}
|
||||
// 设置最终的字段值
|
||||
BeanUtil.setFieldValue(subBean, patternParts.get(length), value);
|
||||
|
||||
// 设置最终的(当前)字段值
|
||||
final Object newSubBean = BeanUtil.setFieldValue(subBean, patternParts.get(length), value);
|
||||
if(newSubBean != subBean && null != previousBean){
|
||||
// 对象变更,重新加入
|
||||
BeanUtil.setFieldValue(previousBean, patternParts.get(length - 1), newSubBean);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -166,7 +169,7 @@ public class BeanPath implements Serializable {
|
||||
private Object get(final List<String> patternParts, final Object bean) {
|
||||
Object subBean = bean;
|
||||
boolean isFirst = true;
|
||||
for (String patternPart : patternParts) {
|
||||
for (final String patternPart : patternParts) {
|
||||
subBean = getFieldValue(subBean, patternPart);
|
||||
if (null == subBean) {
|
||||
// 支持表达式的第一个对象为Bean本身(若用户定义表达式$开头,则不做此操作)
|
||||
|
@@ -118,7 +118,7 @@ public class BeanUtil {
|
||||
if (method.getParameterCount() == 0) {
|
||||
final String name = method.getName();
|
||||
if (name.startsWith("get") || name.startsWith("is")) {
|
||||
if(false == "getClass".equals(name)){
|
||||
if (false == "getClass".equals(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -311,24 +311,32 @@ public class BeanUtil {
|
||||
|
||||
/**
|
||||
* 设置字段值,通过反射设置字段值,并不调用setXXX方法<br>
|
||||
* 对象同样支持Map类型,fieldNameOrIndex即为key
|
||||
* 对象同样支持Map类型,fieldNameOrIndex即为key,支持:
|
||||
* <ul>
|
||||
* <li>Map</li>
|
||||
* <li>List</li>
|
||||
* <li>Bean</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param bean Bean
|
||||
* @param fieldNameOrIndex 字段名或序号,序号支持负数
|
||||
* @param value 值
|
||||
* @return bean,当为数组时,返回一个新的数组
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public static void setFieldValue(final Object bean, final String fieldNameOrIndex, final Object value) {
|
||||
public static Object setFieldValue(final Object bean, final String fieldNameOrIndex, final Object value) {
|
||||
if (bean instanceof Map) {
|
||||
((Map) bean).put(fieldNameOrIndex, value);
|
||||
} else if (bean instanceof List) {
|
||||
ListUtil.setOrPadding((List) bean, Convert.toInt(fieldNameOrIndex), value);
|
||||
} else if (ArrayUtil.isArray(bean)) {
|
||||
ArrayUtil.setOrAppend(bean, Convert.toInt(fieldNameOrIndex), value);
|
||||
// issue#3008,追加产生新数组,此处返回新数组
|
||||
return ArrayUtil.setOrAppend(bean, Convert.toInt(fieldNameOrIndex), value);
|
||||
} else {
|
||||
// 普通Bean对象
|
||||
FieldUtil.setFieldValue(bean, fieldNameOrIndex, value);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -701,7 +701,7 @@ public class IoUtil extends NioUtil {
|
||||
* @return {@link InputStream}
|
||||
* @since 4.0.9
|
||||
*/
|
||||
public static InputStream toMarkSupportStream(final InputStream in) {
|
||||
public static InputStream toMarkSupport(final InputStream in) {
|
||||
if (null == in) {
|
||||
return null;
|
||||
}
|
||||
@@ -711,6 +711,23 @@ public class IoUtil extends NioUtil {
|
||||
return in;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将{@link Reader}转换为支持mark标记的Reader<br>
|
||||
* 若原Reader支持mark标记,则返回原Reader,否则使用{@link BufferedReader} 包装之
|
||||
*
|
||||
* @param reader {@link Reader}
|
||||
* @return {@link Reader}
|
||||
*/
|
||||
public static Reader toMarkSupport(final Reader reader) {
|
||||
if (null == reader) {
|
||||
return null;
|
||||
}
|
||||
if (false == reader.markSupported()) {
|
||||
return new BufferedReader(reader);
|
||||
}
|
||||
return reader;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得{@link PushbackReader}<br>
|
||||
* 如果是{@link PushbackReader}强转返回,否则新建
|
||||
|
@@ -53,6 +53,31 @@ public class ReaderWrapper extends Reader implements Wrapper<Reader> {
|
||||
return raw.read(buffer, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean markSupported() {
|
||||
return this.raw.markSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mark(final int readAheadLimit) throws IOException {
|
||||
this.raw.mark(readAheadLimit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long skip(final long n) throws IOException {
|
||||
return this.raw.skip(n);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ready() throws IOException {
|
||||
return this.raw.ready();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() throws IOException {
|
||||
this.raw.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
raw.close();
|
||||
|
@@ -624,7 +624,8 @@ public class NetUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取主机名称,一次获取会缓存名称
|
||||
* 获取主机名称,一次获取会缓存名称<br>
|
||||
* 注意此方法会触发反向DNS解析,导致阻塞,阻塞时间取决于网络!
|
||||
*
|
||||
* @return 主机名称
|
||||
* @since 5.4.4
|
||||
|
@@ -266,16 +266,17 @@ public class FieldUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置字段值
|
||||
* 设置字段值,如果值类型必须与字段类型匹配,会自动转换对象类型
|
||||
*
|
||||
* @param obj 对象,如果是static字段,此参数为null
|
||||
* @param field 字段
|
||||
* @param value 值,值类型必须与字段类型匹配,不会自动转换对象类型
|
||||
* @param value 值,类型不匹配会自动转换对象类型
|
||||
* @throws UtilException UtilException 包装IllegalAccessException异常
|
||||
*/
|
||||
public static void setFieldValue(final Object obj, final Field field, Object value) throws UtilException {
|
||||
Assert.notNull(field, "Field in [{}] not exist !", obj);
|
||||
|
||||
// 值类型检查和转换
|
||||
final Class<?> fieldType = field.getType();
|
||||
if (null != value) {
|
||||
if (false == fieldType.isAssignableFrom(value.getClass())) {
|
||||
@@ -290,6 +291,18 @@ public class FieldUtil {
|
||||
value = ClassUtil.getDefaultValue(fieldType);
|
||||
}
|
||||
|
||||
setFieldValueExact(obj, field, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置字段值,传入的字段值必须和字段类型一致,否则抛出异常
|
||||
*
|
||||
* @param obj 对象,如果是static字段,此参数为null
|
||||
* @param field 字段
|
||||
* @param value 值,值类型必须与字段类型匹配
|
||||
* @throws UtilException UtilException 包装IllegalAccessException异常
|
||||
*/
|
||||
public static void setFieldValueExact(final Object obj, final Field field, final Object value) throws UtilException {
|
||||
ReflectUtil.setAccessible(field);
|
||||
try {
|
||||
field.set(obj instanceof Class ? null : obj, value);
|
||||
|
@@ -3,6 +3,8 @@ package cn.hutool.core.bean;
|
||||
import cn.hutool.core.lang.test.bean.ExamInfoDict;
|
||||
import cn.hutool.core.lang.test.bean.UserInfoDict;
|
||||
import cn.hutool.core.map.Dict;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import lombok.Data;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -152,4 +154,36 @@ public class BeanPathTest {
|
||||
BeanPath.of("aa.bb").set(dict, "BB");
|
||||
Assert.assertEquals("{aa={bb=BB}}", dict.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void appendArrayTest(){
|
||||
// issue#3008@Github
|
||||
final MyUser myUser = new MyUser();
|
||||
BeanPath.of("hobby[0]").set(myUser, "LOL");
|
||||
BeanPath.of("hobby[1]").set(myUser, "KFC");
|
||||
BeanPath.of("hobby[2]").set(myUser, "COFFE");
|
||||
|
||||
Assert.assertEquals("[LOL, KFC, COFFE]", ArrayUtil.toString(myUser.getHobby()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void appendArrayTest2(){
|
||||
// issue#3008@Github
|
||||
final MyUser2 myUser = new MyUser2();
|
||||
BeanPath.of("myUser.hobby[0]").set(myUser, "LOL");
|
||||
BeanPath.of("myUser.hobby[1]").set(myUser, "KFC");
|
||||
BeanPath.of("myUser.hobby[2]").set(myUser, "COFFE");
|
||||
|
||||
Assert.assertEquals("[LOL, KFC, COFFE]", ArrayUtil.toString(myUser.getMyUser().getHobby()));
|
||||
}
|
||||
|
||||
@Data
|
||||
static class MyUser {
|
||||
private String[] hobby;
|
||||
}
|
||||
|
||||
@Data
|
||||
static class MyUser2 {
|
||||
private MyUser myUser;
|
||||
}
|
||||
}
|
||||
|
@@ -78,10 +78,17 @@ public class NetUtilTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void getLocalHostNameTest() {
|
||||
// 注意此方法会触发反向DNS解析,导致阻塞,阻塞时间取决于网络!
|
||||
Assert.assertNotNull(NetUtil.getLocalHostName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLocalHostTest() {
|
||||
Assert.assertNotNull(NetUtil.getLocalhost());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pingTest(){
|
||||
Assert.assertTrue(NetUtil.ping("127.0.0.1"));
|
||||
|
Reference in New Issue
Block a user