forked from mockito/mockito
/
InstanceField.java
140 lines (122 loc) · 3.7 KB
/
InstanceField.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockito.internal.util.reflection;
import static org.mockito.internal.util.reflection.FieldSetter.setField;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import org.mockito.internal.util.Checks;
/**
* Represents an accessible instance field.
*
* Contains the instance reference on which the field can be read and write.
*/
public class InstanceField {
private final Field field;
private final Object instance;
private FieldReader fieldReader;
/**
* Create a new InstanceField.
*
* @param field The field that should be accessed, note that no checks are performed to ensure
* the field belong to this instance class.
* @param instance The instance from which the field shall be accessed.
*/
public InstanceField(Field field, Object instance) {
this.field = Checks.checkNotNull(field, "field");
this.instance = Checks.checkNotNull(instance, "instance");
}
/**
* Safely read the field.
*
* @return the field value.
* @see FieldReader
*/
public Object read() {
return reader().read();
}
/**
* Set the given value to the field of this instance.
*
* @param value The value that should be written to the field.
* @see FieldSetter
*/
public void set(Object value) {
setField(instance, field,value);
}
/**
* Check that the field is not null.
*
* @return <code>true</code> if <code>null</code>, else <code>false</code>.
*/
public boolean isNull() {
return reader().isNull();
}
/**
* Check if the field is annotated by the given annotation.
*
* @param annotationClass The annotation type to check.
* @return <code>true</code> if the field is annotated by this annotation, else <code>false</code>.
*/
public boolean isAnnotatedBy(Class<? extends Annotation> annotationClass) {
return field.isAnnotationPresent(annotationClass);
}
/**
* Check if the field is synthetic.
*
* @return <code>true</code> if the field is synthetic, else <code>false</code>.
*/
public boolean isSynthetic() {
return field.isSynthetic();
}
/**
* Returns the annotation instance for the given annotation type.
*
* @param annotationClass Tha annotation type to retrieve.
* @param <A> Type of the annotation.
* @return The annotation instance.
*/
public <A extends Annotation> A annotation(Class<A> annotationClass) {
return field.getAnnotation(annotationClass);
}
/**
* Returns the JDK {@link Field} instance.
*
* @return The actual {@link Field} instance.
*/
public Field jdkField() {
return field;
}
private FieldReader reader() {
if (fieldReader == null) {
fieldReader = new FieldReader(instance, field);
}
return fieldReader;
}
/**
* Returns the name of the field.
*
* @return Name of the field.
*/
public String name() {
return field.getName();
}
@Override
public String toString() {
return name();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
InstanceField that = (InstanceField) o;
return field.equals(that.field) && instance.equals(that.instance);
}
@Override
public int hashCode() {
int result = field.hashCode();
result = 31 * result + instance.hashCode();
return result;
}
}