mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-12-07 01:28:34 +08:00
修复ReflectUtil.newInstanceIfPossible传入Object逻辑错误(pr#4160@Github)
This commit is contained in:
parent
472b0d2841
commit
449df10509
@ -31,6 +31,7 @@
|
|||||||
* 【core 】 修复`URLUtil.url`未断开连接问题(pr#4149@Github)
|
* 【core 】 修复`URLUtil.url`未断开连接问题(pr#4149@Github)
|
||||||
* 【core 】 修复`Bimap.put`重复put问题(pr#4150@Github)
|
* 【core 】 修复`Bimap.put`重复put问题(pr#4150@Github)
|
||||||
* 【core 】 修复`StrUtil.str(ByteBuffer, Charset)` 方法修改入参 `ByteBuffer` 的 `position`,导致入参变化 (pr#4153@Github)
|
* 【core 】 修复`StrUtil.str(ByteBuffer, Charset)` 方法修改入参 `ByteBuffer` 的 `position`,导致入参变化 (pr#4153@Github)
|
||||||
|
* 【core 】 修复`ReflectUtil.newInstanceIfPossible`传入Object逻辑错误(pr#4160@Github)
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
# 5.8.41(2025-10-12)
|
# 5.8.41(2025-10-12)
|
||||||
|
|||||||
@ -888,13 +888,19 @@ public class ReflectUtil {
|
|||||||
return (T) ClassUtil.getPrimitiveDefaultValue(type);
|
return (T) ClassUtil.getPrimitiveDefaultValue(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 某些特殊接口的实例化按照默认实现进行
|
if (Object.class != type) {
|
||||||
if (type.isAssignableFrom(AbstractMap.class)) {
|
// 某些特殊接口的实例化按照默认实现进行
|
||||||
type = (Class<T>) HashMap.class;
|
if (type.isAssignableFrom(AbstractMap.class)) {
|
||||||
} else if (type.isAssignableFrom(List.class)) {
|
type = (Class<T>) HashMap.class;
|
||||||
type = (Class<T>) ArrayList.class;
|
} else if (type.isAssignableFrom(List.class)) {
|
||||||
} else if (type.isAssignableFrom(Set.class)) {
|
type = (Class<T>) ArrayList.class;
|
||||||
type = (Class<T>) HashSet.class;
|
} else if (type.isAssignableFrom(Set.class)) {
|
||||||
|
type = (Class<T>) HashSet.class;
|
||||||
|
} else if (type.isAssignableFrom(Queue.class)) {
|
||||||
|
type = (Class<T>) LinkedList.class;
|
||||||
|
} else if (type.isAssignableFrom(Deque.class)) {
|
||||||
|
type = (Class<T>) LinkedList.class;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -151,7 +151,7 @@ public class ReflectUtilTest {
|
|||||||
final TestClass testClass = new TestClass();
|
final TestClass testClass = new TestClass();
|
||||||
final Method method = ReflectUtil.getMethod(TestClass.class, "setA", int.class);
|
final Method method = ReflectUtil.getMethod(TestClass.class, "setA", int.class);
|
||||||
assertThrows(IllegalArgumentException.class,
|
assertThrows(IllegalArgumentException.class,
|
||||||
() -> ReflectUtil.invoke(testClass, method, "NaN"));
|
() -> ReflectUtil.invoke(testClass, method, "NaN"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -210,6 +210,7 @@ public class ReflectUtilTest {
|
|||||||
private String n;
|
private String n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("UnusedReturnValue")
|
||||||
public static Method getMethodWithReturnTypeCheck(final Class<?> clazz, final boolean ignoreCase, final String methodName, final Class<?>... paramTypes) throws SecurityException {
|
public static Method getMethodWithReturnTypeCheck(final Class<?> clazz, final boolean ignoreCase, final String methodName, final Class<?>... paramTypes) throws SecurityException {
|
||||||
if (null == clazz || StrUtil.isBlank(methodName)) {
|
if (null == clazz || StrUtil.isBlank(methodName)) {
|
||||||
return null;
|
return null;
|
||||||
@ -220,9 +221,9 @@ public class ReflectUtilTest {
|
|||||||
if (ArrayUtil.isNotEmpty(methods)) {
|
if (ArrayUtil.isNotEmpty(methods)) {
|
||||||
for (final Method method : methods) {
|
for (final Method method : methods) {
|
||||||
if (StrUtil.equals(methodName, method.getName(), ignoreCase)
|
if (StrUtil.equals(methodName, method.getName(), ignoreCase)
|
||||||
&& ClassUtil.isAllAssignableFrom(method.getParameterTypes(), paramTypes)
|
&& ClassUtil.isAllAssignableFrom(method.getParameterTypes(), paramTypes)
|
||||||
&& (res == null
|
&& (res == null
|
||||||
|| res.getReturnType().isAssignableFrom(method.getReturnType()))) {
|
|| res.getReturnType().isAssignableFrom(method.getReturnType()))) {
|
||||||
res = method;
|
res = method;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -300,6 +301,7 @@ public class ReflectUtilTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class C2 extends C1 {
|
class C2 extends C1 {
|
||||||
|
@SuppressWarnings("RedundantMethodOverride")
|
||||||
@Override
|
@Override
|
||||||
public void getA() {
|
public void getA() {
|
||||||
|
|
||||||
@ -307,7 +309,7 @@ public class ReflectUtilTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void newInstanceIfPossibleTest(){
|
public void newInstanceIfPossibleTest() {
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
final int intValue = ReflectUtil.newInstanceIfPossible(int.class);
|
final int intValue = ReflectUtil.newInstanceIfPossible(int.class);
|
||||||
assertEquals(0, intValue);
|
assertEquals(0, intValue);
|
||||||
@ -330,19 +332,19 @@ public class ReflectUtilTest {
|
|||||||
|
|
||||||
public static class JdbcDialects {
|
public static class JdbcDialects {
|
||||||
private static final List<Number> DIALECTS =
|
private static final List<Number> DIALECTS =
|
||||||
Arrays.asList(1L, 2L, 3L);
|
Arrays.asList(1L, 2L, 3L);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void setFieldValueWithFinalTest() {
|
public void setFieldValueWithFinalTest() {
|
||||||
final String fieldName = "DIALECTS";
|
final String fieldName = "DIALECTS";
|
||||||
final List<Number> dialects =
|
final List<Number> dialects =
|
||||||
Arrays.asList(
|
Arrays.asList(
|
||||||
1,
|
1,
|
||||||
2,
|
2,
|
||||||
3,
|
3,
|
||||||
99
|
99
|
||||||
);
|
);
|
||||||
final Field field = ReflectUtil.getField(JdbcDialects.class, fieldName);
|
final Field field = ReflectUtil.getField(JdbcDialects.class, fieldName);
|
||||||
ReflectUtil.removeFinalModify(field);
|
ReflectUtil.removeFinalModify(field);
|
||||||
ReflectUtil.setFieldValue(JdbcDialects.class, fieldName, dialects);
|
ReflectUtil.setFieldValue(JdbcDialects.class, fieldName, dialects);
|
||||||
@ -351,24 +353,63 @@ public class ReflectUtilTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void issue2625Test(){
|
public void issue2625Test() {
|
||||||
// 内部类继承的情况下父类方法会被定义为桥接方法,因此按照pr#1965@Github判断返回值的继承关系来代替判断桥接。
|
// 内部类继承的情况下父类方法会被定义为桥接方法,因此按照pr#1965@Github判断返回值的继承关系来代替判断桥接。
|
||||||
final Method getThis = ReflectUtil.getMethod(A.C.class, "getThis");
|
final Method getThis = ReflectUtil.getMethod(A.C.class, "getThis");
|
||||||
assertTrue(getThis.isBridge());
|
assertTrue(getThis.isBridge());
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("InnerClassMayBeStatic")
|
@SuppressWarnings("InnerClassMayBeStatic")
|
||||||
public class A{
|
public class A {
|
||||||
|
|
||||||
public class C extends B{
|
public class C extends B {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected class B{
|
protected class B {
|
||||||
public B getThis(){
|
public B getThis() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void newInstanceIfPossibleTest2() {
|
||||||
|
// 测试Object.class不应该被错误地实例化为HashMap,应该返回Object实例
|
||||||
|
Object objectInstance = ReflectUtil.newInstanceIfPossible(Object.class);
|
||||||
|
assertNotNull(objectInstance);
|
||||||
|
assertEquals(Object.class, objectInstance.getClass());
|
||||||
|
|
||||||
|
// 测试Map.class能够正确实例化为HashMap
|
||||||
|
Map<?, ?> mapInstance = ReflectUtil.newInstanceIfPossible(Map.class);
|
||||||
|
assertNotNull(mapInstance);
|
||||||
|
assertInstanceOf(HashMap.class, mapInstance);
|
||||||
|
|
||||||
|
// 测试Collection.class能够正确实例化为ArrayList
|
||||||
|
Collection<?> collectionInstance = ReflectUtil.newInstanceIfPossible(Collection.class);
|
||||||
|
assertNotNull(collectionInstance);
|
||||||
|
assertInstanceOf(ArrayList.class, collectionInstance);
|
||||||
|
|
||||||
|
|
||||||
|
// 测试List.class能够正确实例化为ArrayList
|
||||||
|
List<?> listInstance = ReflectUtil.newInstanceIfPossible(List.class);
|
||||||
|
assertNotNull(listInstance);
|
||||||
|
assertInstanceOf(ArrayList.class, listInstance);
|
||||||
|
|
||||||
|
// 测试Set.class能够正确实例化为HashSet
|
||||||
|
Set<?> setInstance = ReflectUtil.newInstanceIfPossible(Set.class);
|
||||||
|
assertNotNull(setInstance);
|
||||||
|
assertInstanceOf(HashSet.class, setInstance);
|
||||||
|
|
||||||
|
// 测试Queue接口能够正确实例化为LinkedList
|
||||||
|
Queue<?> queueInstance = ReflectUtil.newInstanceIfPossible(Queue.class);
|
||||||
|
assertNotNull(queueInstance);
|
||||||
|
assertInstanceOf(LinkedList.class, queueInstance);
|
||||||
|
|
||||||
|
// 测试Deque接口能够正确实例化为LinkedList
|
||||||
|
Deque<?> dequeInstance = ReflectUtil.newInstanceIfPossible(Deque.class);
|
||||||
|
assertNotNull(dequeInstance);
|
||||||
|
assertInstanceOf(LinkedList.class, dequeInstance);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user