001    package org.junit.runners.model;
002    
003    import java.lang.annotation.Annotation;
004    import java.lang.reflect.Field;
005    
006    import org.junit.runners.BlockJUnit4ClassRunner;
007    
008    /**
009     * Represents a field on a test class (currently used only for Rules in
010     * {@link BlockJUnit4ClassRunner}, but custom runners can make other uses)
011     *
012     * @since 4.7
013     */
014    public class FrameworkField extends FrameworkMember<FrameworkField> {
015        private final Field field;
016    
017        /**
018         * Returns a new {@code FrameworkField} for {@code field}.
019         *
020         * <p>Access relaxed to {@code public} since version 4.13.1.
021         */
022        public FrameworkField(Field field) {
023            if (field == null) {
024                throw new NullPointerException(
025                        "FrameworkField cannot be created without an underlying field.");
026            }
027            this.field = field;
028    
029            if (isPublic()) {
030                // This field could be a public field in a package-scope base class
031                try {
032                    field.setAccessible(true);
033                } catch (SecurityException e) {
034                    // We may get an IllegalAccessException when we try to access the field
035                }
036            }
037        }
038    
039        @Override
040        public String getName() {
041            return getField().getName();
042        }
043    
044        public Annotation[] getAnnotations() {
045            return field.getAnnotations();
046        }
047    
048        public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
049            return field.getAnnotation(annotationType);
050        }
051    
052        @Override
053        public boolean isShadowedBy(FrameworkField otherMember) {
054            return otherMember.getName().equals(getName());
055        }
056    
057        @Override
058        boolean isBridgeMethod() {
059            return false;
060        }
061    
062        @Override
063        protected int getModifiers() {
064            return field.getModifiers();
065        }
066    
067        /**
068         * @return the underlying java Field
069         */
070        public Field getField() {
071            return field;
072        }
073    
074        /**
075         * @return the underlying Java Field type
076         * @see java.lang.reflect.Field#getType()
077         */
078        @Override
079        public Class<?> getType() {
080            return field.getType();
081        }
082        
083        @Override
084        public Class<?> getDeclaringClass() {
085            return field.getDeclaringClass();
086        }
087    
088        /**
089         * Attempts to retrieve the value of this field on {@code target}
090         */
091        public Object get(Object target) throws IllegalArgumentException, IllegalAccessException {
092            return field.get(target);
093        }
094    
095        @Override
096        public String toString() {
097            return field.toString();
098        }
099    }