private static Field asSetableField ( Field field , Object target , Class < ? > valueType , Object value , boolean makeAccessibleCopy ) throws IllegalAccessException { // Must do the checks exactly in the same order as JVM if we want identical error messages. // JVM doesn't do this, since it cannot happen without reloading, we do it first of all. if ( isDeleted ( field ) ) { throw Exceptions . noSuchFieldError ( field ) ; } Class < ? > clazz = field . getDeclaringClass ( ) ; int mods = field . getModifiers ( ) ; if ( field . isAccessible ( ) || Modifier . isPublic ( mods & jlClassGetModifiers ( clazz ) ) ) { //More expensive check not required / copy not required } else { //More expensive check required Class < ? > callerClass = getCallerClass ( ) ; JVM . ensureMemberAccess ( callerClass , clazz , target , mods ) ; if ( makeAccessibleCopy ) { //TODO: This code is not covered by a test. It needs a non-reloadable type with non-public // field, being accessed reflectively from a context that is "priviliged" to access it without setting the access flag. field = JVM . copyField ( field ) ; // copy: we must not change accessible flag on original field! field . setAccessible ( true ) ; } } if ( isPrimitive ( valueType ) ) { //It seems for primitive types, the order of the checks (in Sun JVM) is different! typeCheckFieldSet ( field , valueType , value ) ; if ( ! field . isAccessible ( ) && Modifier . isFinal ( mods ) ) { throw Exceptions . illegalSetFinalFieldException ( field , field . getType ( ) , coerce ( value , field . getType ( ) ) ) ; } } else { if ( ! field . isAccessible ( ) && Modifier . isFinal ( mods ) ) { throw Exceptions . illegalSetFinalFieldException ( field , valueType , value ) ; } typeCheckFieldSet ( field , valueType , value ) ; } return makeAccessibleCopy ? field : null ; }
Performs all necessary checks that need to be done before a field set should be allowed .