• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hazendaz / jmockit1 / 496

15 Nov 2025 05:33PM UTC coverage: 72.192% (-0.008%) from 72.2%
496

push

github

web-flow
Merge pull request #412 from hazendaz/renovate/major-spring-core

Update spring core to v7 (major)

5677 of 8360 branches covered (67.91%)

Branch coverage included in aggregate %.

11922 of 16018 relevant lines covered (74.43%)

0.74 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.73
/main/src/main/java/mockit/internal/reflection/FieldReflection.java
1
/*
2
 * MIT License
3
 * Copyright (c) 2006-2025 JMockit developers
4
 * See LICENSE file for full license text.
5
 */
6
package mockit.internal.reflection;
7

8
import static java.lang.reflect.Modifier.isStatic;
9

10
import static mockit.internal.util.Utilities.ensureThatMemberIsAccessible;
11

12
import edu.umd.cs.findbugs.annotations.NonNull;
13
import edu.umd.cs.findbugs.annotations.Nullable;
14

15
import java.lang.reflect.Field;
16
import java.lang.reflect.Type;
17

18
import mockit.internal.util.AutoBoxing;
19
import mockit.internal.util.Utilities;
20

21
public final class FieldReflection {
22
    private FieldReflection() {
23
    }
24

25
    @Nullable
26
    public static <T> T getFieldValue(@NonNull Field field, @Nullable Object targetObject) {
27
        ensureThatMemberIsAccessible(field);
1✔
28

29
        if (targetObject != null && !field.getDeclaringClass().isInstance(targetObject)) {
1!
30
            Field outerInstanceField = getDeclaredField(targetObject.getClass(), "this$0", true);
×
31
            targetObject = getFieldValue(outerInstanceField, targetObject);
×
32
        }
33

34
        try {
35
            // noinspection unchecked
36
            return (T) field.get(targetObject);
1✔
37
        } catch (IllegalAccessException e) {
×
38
            throw new RuntimeException(e);
×
39
        }
40
    }
41

42
    @Nullable
43
    public static <T> T getField(@NonNull Class<?> theClass, @NonNull String fieldName, @Nullable Object targetObject) {
44
        Field field = getDeclaredField(theClass, fieldName, targetObject != null);
1✔
45
        return getFieldValue(field, targetObject);
1✔
46
    }
47

48
    @Nullable
49
    public static <T> T getField(@NonNull Class<?> theClass, @NonNull Class<T> fieldType,
50
            @Nullable Object targetObject) {
51
        Field field = getDeclaredField(theClass, fieldType, targetObject != null, false);
1✔
52
        return getFieldValue(field, targetObject);
1✔
53
    }
54

55
    public static void setField(@NonNull Class<?> theClass, @Nullable Object targetObject, @Nullable String fieldName,
56
            @Nullable Object fieldValue) {
57
        boolean instanceField = targetObject != null;
1✔
58
        Field field;
59

60
        if (fieldName != null) {
1✔
61
            field = getDeclaredField(theClass, fieldName, instanceField);
1✔
62
        } else if (fieldValue != null) {
1✔
63
            field = getDeclaredField(theClass, fieldValue.getClass(), instanceField, true);
1✔
64
        } else {
65
            throw new IllegalArgumentException("Missing field value when setting field by type");
1✔
66
        }
67

68
        setFieldValue(field, targetObject, fieldValue);
1✔
69
    }
1✔
70

71
    @NonNull
72
    public static Field getDeclaredField(@NonNull Class<?> theClass, @NonNull String fieldName, boolean instanceField) {
73
        try {
74
            return theClass.getDeclaredField(fieldName);
1✔
75
        } catch (NoSuchFieldException ignore) {
1✔
76
            Class<?> superClass = theClass.getSuperclass();
1✔
77

78
            if (superClass != null && superClass != Object.class) {
1!
79
                // noinspection TailRecursion
80
                return getDeclaredField(superClass, fieldName, instanceField);
1✔
81
            }
82

83
            String kind = instanceField ? "instance" : "static";
1✔
84
            throw new IllegalArgumentException(
1✔
85
                    "No " + kind + " field of name \"" + fieldName + "\" found in " + theClass);
86
        }
87
    }
88

89
    @NonNull
90
    private static Field getDeclaredField(@NonNull Class<?> theClass, @NonNull Type desiredType, boolean instanceField,
91
            boolean forAssignment) {
92
        Field found = getDeclaredFieldInSingleClass(theClass, desiredType, instanceField, forAssignment);
1✔
93

94
        if (found == null) {
1✔
95
            Class<?> superClass = theClass.getSuperclass();
1✔
96

97
            if (superClass != null && superClass != Object.class) {
1!
98
                // noinspection TailRecursion
99
                return getDeclaredField(superClass, desiredType, instanceField, forAssignment);
1✔
100
            }
101

102
            StringBuilder errorMsg = new StringBuilder(instanceField ? "Instance" : "Static");
1✔
103
            String typeName = getTypeName(desiredType);
1✔
104
            errorMsg.append(" field of type ").append(typeName).append(" not found in ").append(theClass);
1✔
105
            throw new IllegalArgumentException(errorMsg.toString());
1✔
106
        }
107

108
        return found;
1✔
109
    }
110

111
    @Nullable
112
    private static Field getDeclaredFieldInSingleClass(@NonNull Class<?> theClass, @NonNull Type desiredType,
113
            boolean instanceField, boolean forAssignment) {
114
        Field found = null;
1✔
115

116
        for (Field field : theClass.getDeclaredFields()) {
1✔
117
            if (!field.isSynthetic()) {
1✔
118
                Type fieldType = field.getGenericType();
1✔
119

120
                if (instanceField != isStatic(field.getModifiers())
1✔
121
                        && isCompatibleFieldType(fieldType, desiredType, forAssignment)) {
1✔
122
                    if (found != null) {
1✔
123
                        String message = errorMessageForMoreThanOneFieldFound(desiredType, instanceField, forAssignment,
1✔
124
                                found, field);
125
                        throw new IllegalArgumentException(message);
1✔
126
                    }
127

128
                    found = field;
1✔
129
                }
130
            }
131
        }
132

133
        return found;
1✔
134
    }
135

136
    private static boolean isCompatibleFieldType(@NonNull Type fieldType, @NonNull Type desiredType,
137
            boolean forAssignment) {
138
        Class<?> fieldClass = Utilities.getClassType(fieldType);
1✔
139
        Class<?> desiredClass = Utilities.getClassType(desiredType);
1✔
140

141
        if (ParameterReflection.isSameTypeIgnoringAutoBoxing(desiredClass, fieldClass)) {
1✔
142
            return true;
1✔
143
        }
144

145
        if (forAssignment) {
1✔
146
            return fieldClass.isAssignableFrom(desiredClass);
1✔
147
        }
148

149
        return desiredClass.isAssignableFrom(fieldClass) || fieldClass.isAssignableFrom(desiredClass);
1!
150
    }
151

152
    private static String errorMessageForMoreThanOneFieldFound(@NonNull Type desiredFieldType, boolean instanceField,
153
            boolean forAssignment, @NonNull Field firstField, @NonNull Field secondField) {
154
        return "More than one " + (instanceField ? "instance" : "static") + " field " + (forAssignment ? "to" : "from")
1✔
155
                + " which a value of type " + getTypeName(desiredFieldType)
1✔
156
                + (forAssignment ? " can be assigned" : " can be read") + " exists in "
1✔
157
                + secondField.getDeclaringClass() + ": " + firstField.getName() + ", " + secondField.getName();
1✔
158
    }
159

160
    @NonNull
161
    private static String getTypeName(@NonNull Type type) {
162
        Class<?> classType = Utilities.getClassType(type);
1✔
163
        Class<?> primitiveType = AutoBoxing.getPrimitiveType(classType);
1✔
164

165
        if (primitiveType != null) {
1✔
166
            return primitiveType + " or " + classType.getSimpleName();
1✔
167
        }
168

169
        String name = classType.getName();
1✔
170
        return name.startsWith("java.lang.") ? name.substring(10) : name;
1✔
171
    }
172

173
    public static void setFieldValue(@NonNull Field field, @Nullable Object targetObject, @Nullable Object value) {
174
        ensureThatMemberIsAccessible(field);
1✔
175

176
        if (targetObject != null && !field.getDeclaringClass().isInstance(targetObject)) {
1!
177
            Field outerInstanceField = getDeclaredField(targetObject.getClass(), "this$0", true);
×
178
            targetObject = getFieldValue(outerInstanceField, targetObject);
×
179
        }
180

181
        try {
182
            field.set(targetObject, value);
1✔
183
        } catch (IllegalAccessException e) {
1✔
184
            throw new RuntimeException(e);
1✔
185
        }
1✔
186
    }
1✔
187
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc