changeset 4875:b836de51e07a

8009677: Better setting of setters Reviewed-by: ahgross, jrose, twisti
author andrew
date Wed, 17 Apr 2013 23:54:20 +0100
parents 8abc50bce580
children 29b45a693cf0
files src/share/classes/java/lang/invoke/MethodHandles.java
diffstat 1 files changed, 8 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/lang/invoke/MethodHandles.java	Thu Mar 14 17:27:32 2013 +0100
+++ b/src/share/classes/java/lang/invoke/MethodHandles.java	Wed Apr 17 23:54:20 2013 +0100
@@ -689,7 +689,7 @@
         }
         private MethodHandle accessConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
             assert(ctor.isConstructor());
-            checkAccess(refc, ctor);
+            checkAccess(refc, ctor, false /* is_setter */);
             MethodHandle rawMH = MethodHandleImpl.findMethod(ctor, false, lookupClassOrNull());
             MethodHandle allocMH = MethodHandleImpl.makeAllocator(rawMH);
             assert(!MethodHandleNatives.isCallerSensitive(ctor));  // maybeBindCaller not relevant here
@@ -1052,7 +1052,7 @@
         public MethodHandle unreflectConstructor(Constructor c) throws IllegalAccessException {
             MemberName ctor = new MemberName(c);
             assert(ctor.isConstructor());
-            if (!c.isAccessible())  checkAccess(c.getDeclaringClass(), ctor);
+            if (!c.isAccessible())  checkAccess(c.getDeclaringClass(), ctor, false /* is_setter */);
             MethodHandle rawCtor = MethodHandleImpl.findMethod(ctor, false, lookupClassOrNull());
             assert(!MethodHandleNatives.isCallerSensitive(ctor));  // maybeBindCaller not relevant here
             MethodHandle allocator = MethodHandleImpl.makeAllocator(rawCtor);
@@ -1205,14 +1205,17 @@
             else if (wantStatic != m.isStatic())
                 message = wantStatic ? "expected a static method" : "expected a non-static method";
             else
-                { checkAccess(refc, m); return; }
+                { checkAccess(refc, m, false /* is_setter */); return; }
             throw m.makeAccessException(message, this);
         }
 
-        void checkAccess(Class<?> refc, MemberName m) throws IllegalAccessException {
+        void checkAccess(Class<?> refc, MemberName m, boolean isSetter) throws IllegalAccessException {
             int allowedModes = this.allowedModes;
             if (allowedModes == TRUSTED)  return;
             int mods = m.getModifiers();
+            if (m.isField() && Modifier.isFinal(mods) && isSetter) {
+              throw m.makeAccessException("unexpected set of a final field", this);
+            }
             if (Modifier.isPublic(mods) && Modifier.isPublic(refc.getModifiers()) && allowedModes != 0)
                 return;  // common case
             int requestedModes = fixmods(mods);  // adjust 0 => PACKAGE
@@ -1311,7 +1314,7 @@
                                                 : "expected a non-static field", this);
             if (trusted)
                 return MethodHandleImpl.accessField(field, isSetter, lookupClassOrNull());
-            checkAccess(refc, field);
+            checkAccess(refc, field, isSetter);
             MethodHandle mh = MethodHandleImpl.accessField(field, isSetter, lookupClassOrNull());
             return restrictProtectedReceiver(field, mh);
         }