Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8177148

Receiver type restriction on protected access is not documented for some MethodHandle factories

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P5 P5
    • 11
    • 9
    • core-libs
    • None

      MethodHandle::Lookup factories restrict receiver type to the lookup class when a protected instance member is accessed.
      That's discussed in the class-level Javadoc of Lookup (paragraph "If the desired member is protected, the usual JVM rules apply..."),
      and, more formally, in the findVirtual's Javadoc: "The first argument will be of type refc if the lookup class has full privileges to access the member. Otherwise the member must be protected and the first argument will be restricted in type to the lookup class."
      However, Javadocs of other factory methods don't specify that.

      The affected methods are:
      unreflect
      findGetter
      findSetter
      unreflectGetter
      unreflectSetter
      findVarHandle
      unreflectVarHandle

      Example:
      ====================================
      public class B extends A {
          public static void main(String[] args) throws Throwable {
              MethodHandle mh = lookup().findGetter(A.class, "f", int.class);
              System.out.println(mh.type());

              MethodHandle mh2 = lookup().findSetter(A.class, "f", int.class);
              System.out.println(mh2.type());

              VarHandle vh = lookup().findVarHandle(A.class, "f", int.class);
              System.out.println(vh.coordinateTypes());

              Field f = A.class.getDeclaredField("f");

              MethodHandle mh3 = lookup().unreflectGetter(f);
              System.out.println(mh3.type());

              MethodHandle mh4 = lookup().unreflectSetter(f);
              System.out.println(mh4.type());

              VarHandle vh2 = lookup().unreflectVarHandle(f);
              System.out.println(vh2.coordinateTypes());

              Method m = A.class.getDeclaredMethod("m");

              MethodHandle mh5 = lookup().unreflect(m);
              System.out.println(mh5);
          }
      }

      package pkg;
      public class A {
          protected int f;
          protected void m() { }
      }
      ====================================
      Output (note that all recevier types are B, not A):
      (B)int
      (B,int)void
      [class B]
      (B)int
      (B,int)void
      [class B]
      MethodHandle(B)void

            vtheeyarath Vivek Theeyarath (Inactive)
            slukyanov Stanislav Lukyanov (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: