82 * <p>
83 * For any given caller class {@code C}, the lookup object returned by this call
84 * has equivalent capabilities to any lookup object
85 * supplied by the JVM to the bootstrap method of an
86 * <a href="package-summary.html#indyinsn">invokedynamic instruction</a>
87 * executing in the same caller class {@code C}.
88 * @return a lookup object for the caller of this method, with private access
89 */
90 @CallerSensitive
91 public static Lookup lookup() {
92 return new Lookup(Reflection.getCallerClass());
93 }
94
95 /**
96 * Returns a {@link Lookup lookup object} which is trusted minimally.
97 * It can only be used to create method handles to
98 * publicly accessible fields and methods.
99 * <p>
100 * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
101 * of this lookup object will be {@link java.lang.Object}.
102 *
103 * <p style="font-size:smaller;">
104 * <em>Discussion:</em>
105 * The lookup class can be changed to any other class {@code C} using an expression of the form
106 * {@link Lookup#in publicLookup().in(C.class)}.
107 * Since all classes have equal access to public names,
108 * such a change would confer no new access rights.
109 * A public lookup object is always subject to
110 * <a href="MethodHandles.Lookup.html#secmgr">security manager checks</a>.
111 * Also, it cannot access
112 * <a href="MethodHandles.Lookup.html#callsens">caller sensitive methods</a>.
113 * @return a lookup object which is trusted minimally
114 */
115 public static Lookup publicLookup() {
116 return Lookup.PUBLIC_LOOKUP;
117 }
118
119 /**
120 * Performs an unchecked "crack" of a
121 * <a href="MethodHandleInfo.html#directmh">direct method handle</a>.
122 * The result is as if the user had obtained a lookup object capable enough
123 * to crack the target method handle, called
124 * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect}
125 * on the target to obtain its symbolic reference, and then called
126 * {@link java.lang.invoke.MethodHandleInfo#reflectAs MethodHandleInfo.reflectAs}
127 * to resolve the symbolic reference to a member.
128 * <p>
624
625 /**
626 * Creates a lookup on the specified new lookup class.
627 * The resulting object will report the specified
628 * class as its own {@link #lookupClass lookupClass}.
629 * <p>
630 * However, the resulting {@code Lookup} object is guaranteed
631 * to have no more access capabilities than the original.
632 * In particular, access capabilities can be lost as follows:<ul>
633 * <li>If the new lookup class differs from the old one,
634 * protected members will not be accessible by virtue of inheritance.
635 * (Protected members may continue to be accessible because of package sharing.)
636 * <li>If the new lookup class is in a different package
637 * than the old one, protected and default (package) members will not be accessible.
638 * <li>If the new lookup class is not within the same package member
639 * as the old one, private members will not be accessible.
640 * <li>If the new lookup class is not accessible to the old lookup class,
641 * then no members, not even public members, will be accessible.
642 * (In all other cases, public members will continue to be accessible.)
643 * </ul>
644 *
645 * @param requestedLookupClass the desired lookup class for the new lookup object
646 * @return a lookup object which reports the desired lookup class
647 * @throws NullPointerException if the argument is null
648 */
649 public Lookup in(Class<?> requestedLookupClass) {
650 Objects.requireNonNull(requestedLookupClass);
651 if (allowedModes == TRUSTED) // IMPL_LOOKUP can make any lookup at all
652 return new Lookup(requestedLookupClass, ALL_MODES);
653 if (requestedLookupClass == this.lookupClass)
654 return this; // keep same capabilities
655 int newModes = (allowedModes & (ALL_MODES & ~PROTECTED));
656 if ((newModes & PACKAGE) != 0
657 && !VerifyAccess.isSamePackage(this.lookupClass, requestedLookupClass)) {
658 newModes &= ~(PACKAGE|PRIVATE);
659 }
660 // Allow nestmate lookups to be created without special privilege:
661 if ((newModes & PRIVATE) != 0
662 && !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) {
663 newModes &= ~PRIVATE;
922 * @param refc the class or interface from which the method is accessed
923 * @param type the type of the method, with the receiver argument omitted, and a void return type
924 * @return the desired method handle
925 * @throws NoSuchMethodException if the constructor does not exist
926 * @throws IllegalAccessException if access checking fails
927 * or if the method's variable arity modifier bit
928 * is set and {@code asVarargsCollector} fails
929 * @exception SecurityException if a security manager is present and it
930 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
931 * @throws NullPointerException if any argument is null
932 */
933 public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
934 String name = "<init>";
935 MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
936 return getDirectConstructor(refc, ctor);
937 }
938
939 /**
940 * Looks up a class by name from the lookup context defined by this {@code Lookup} object. The static
941 * initializer of the class is not run.
942 *
943 * @param targetName the fully qualified name of the class to be looked up.
944 * @return the requested class.
945 * @exception SecurityException if a security manager is present and it
946 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
947 * @throws LinkageError if the linkage fails
948 * @throws ClassNotFoundException if the class does not exist.
949 * @throws IllegalAccessException if the class is not accessible, using the allowed access
950 * modes.
951 * @exception SecurityException if a security manager is present and it
952 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
953 * @since 9
954 */
955 public Class<?> findClass(String targetName) throws ClassNotFoundException, IllegalAccessException {
956 Class<?> targetClass = Class.forName(targetName, false, lookupClass.getClassLoader());
957 return accessClass(targetClass);
958 }
959
960 /**
961 * Determines if a class can be accessed from the lookup context defined by this {@code Lookup} object. The
962 * static initializer of the class is not run.
963 *
964 * @param targetClass the class to be access-checked
965 *
966 * @return the class that has been access-checked
967 *
968 * @throws IllegalAccessException if the class is not accessible from the lookup class, using the allowed access
969 * modes.
970 * @exception SecurityException if a security manager is present and it
971 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
972 * @since 9
973 */
974 public Class<?> accessClass(Class<?> targetClass) throws IllegalAccessException {
975 if (!VerifyAccess.isClassAccessible(targetClass, lookupClass, allowedModes)) {
976 throw new MemberName(targetClass).makeAccessException("access violation", this);
977 }
978 checkSecurityManager(targetClass, null);
979 return targetClass;
980 }
981
982 /**
|
82 * <p>
83 * For any given caller class {@code C}, the lookup object returned by this call
84 * has equivalent capabilities to any lookup object
85 * supplied by the JVM to the bootstrap method of an
86 * <a href="package-summary.html#indyinsn">invokedynamic instruction</a>
87 * executing in the same caller class {@code C}.
88 * @return a lookup object for the caller of this method, with private access
89 */
90 @CallerSensitive
91 public static Lookup lookup() {
92 return new Lookup(Reflection.getCallerClass());
93 }
94
95 /**
96 * Returns a {@link Lookup lookup object} which is trusted minimally.
97 * It can only be used to create method handles to
98 * publicly accessible fields and methods.
99 * <p>
100 * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
101 * of this lookup object will be {@link java.lang.Object}.
102 * Consequently, the lookup context of this lookup object will be the bootstrap
103 * class loader, which means it cannot find user classes.
104 *
105 * <p style="font-size:smaller;">
106 * <em>Discussion:</em>
107 * The lookup class can be changed to any other class {@code C} using an expression of the form
108 * {@link Lookup#in publicLookup().in(C.class)}.
109 * Since all classes have equal access to public names,
110 * such a change would confer no new access rights,
111 * but may change the lookup context by virtue of changing the class loader.
112 * A public lookup object is always subject to
113 * <a href="MethodHandles.Lookup.html#secmgr">security manager checks</a>.
114 * Also, it cannot access
115 * <a href="MethodHandles.Lookup.html#callsens">caller sensitive methods</a>.
116 * @return a lookup object which is trusted minimally
117 */
118 public static Lookup publicLookup() {
119 return Lookup.PUBLIC_LOOKUP;
120 }
121
122 /**
123 * Performs an unchecked "crack" of a
124 * <a href="MethodHandleInfo.html#directmh">direct method handle</a>.
125 * The result is as if the user had obtained a lookup object capable enough
126 * to crack the target method handle, called
127 * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect}
128 * on the target to obtain its symbolic reference, and then called
129 * {@link java.lang.invoke.MethodHandleInfo#reflectAs MethodHandleInfo.reflectAs}
130 * to resolve the symbolic reference to a member.
131 * <p>
627
628 /**
629 * Creates a lookup on the specified new lookup class.
630 * The resulting object will report the specified
631 * class as its own {@link #lookupClass lookupClass}.
632 * <p>
633 * However, the resulting {@code Lookup} object is guaranteed
634 * to have no more access capabilities than the original.
635 * In particular, access capabilities can be lost as follows:<ul>
636 * <li>If the new lookup class differs from the old one,
637 * protected members will not be accessible by virtue of inheritance.
638 * (Protected members may continue to be accessible because of package sharing.)
639 * <li>If the new lookup class is in a different package
640 * than the old one, protected and default (package) members will not be accessible.
641 * <li>If the new lookup class is not within the same package member
642 * as the old one, private members will not be accessible.
643 * <li>If the new lookup class is not accessible to the old lookup class,
644 * then no members, not even public members, will be accessible.
645 * (In all other cases, public members will continue to be accessible.)
646 * </ul>
647 * <p>
648 * The resulting lookup's capabilities for loading classes
649 * (used during {@link #findClass} invocations)
650 * are determined by the lookup class' loader,
651 * which may change due to this operation.
652 *
653 * @param requestedLookupClass the desired lookup class for the new lookup object
654 * @return a lookup object which reports the desired lookup class
655 * @throws NullPointerException if the argument is null
656 */
657 public Lookup in(Class<?> requestedLookupClass) {
658 Objects.requireNonNull(requestedLookupClass);
659 if (allowedModes == TRUSTED) // IMPL_LOOKUP can make any lookup at all
660 return new Lookup(requestedLookupClass, ALL_MODES);
661 if (requestedLookupClass == this.lookupClass)
662 return this; // keep same capabilities
663 int newModes = (allowedModes & (ALL_MODES & ~PROTECTED));
664 if ((newModes & PACKAGE) != 0
665 && !VerifyAccess.isSamePackage(this.lookupClass, requestedLookupClass)) {
666 newModes &= ~(PACKAGE|PRIVATE);
667 }
668 // Allow nestmate lookups to be created without special privilege:
669 if ((newModes & PRIVATE) != 0
670 && !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) {
671 newModes &= ~PRIVATE;
930 * @param refc the class or interface from which the method is accessed
931 * @param type the type of the method, with the receiver argument omitted, and a void return type
932 * @return the desired method handle
933 * @throws NoSuchMethodException if the constructor does not exist
934 * @throws IllegalAccessException if access checking fails
935 * or if the method's variable arity modifier bit
936 * is set and {@code asVarargsCollector} fails
937 * @exception SecurityException if a security manager is present and it
938 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
939 * @throws NullPointerException if any argument is null
940 */
941 public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
942 String name = "<init>";
943 MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
944 return getDirectConstructor(refc, ctor);
945 }
946
947 /**
948 * Looks up a class by name from the lookup context defined by this {@code Lookup} object. The static
949 * initializer of the class is not run.
950 * <p>
951 * The lookup context here is determined by the {@linkplain #lookupClass() lookup class}, its class
952 * loader, and the {@linkplain #lookupModes() lookup modes}. In particular, the method first attempts to
953 * load the requested class, and then determines whether the class is accessible to this lookup object.
954 *
955 * @param targetName the fully qualified name of the class to be looked up.
956 * @return the requested class.
957 * @exception SecurityException if a security manager is present and it
958 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
959 * @throws LinkageError if the linkage fails
960 * @throws ClassNotFoundException if the class cannot be loaded by the lookup class' loader.
961 * @throws IllegalAccessException if the class is not accessible, using the allowed access
962 * modes.
963 * @exception SecurityException if a security manager is present and it
964 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
965 * @since 9
966 */
967 public Class<?> findClass(String targetName) throws ClassNotFoundException, IllegalAccessException {
968 Class<?> targetClass = Class.forName(targetName, false, lookupClass.getClassLoader());
969 return accessClass(targetClass);
970 }
971
972 /**
973 * Determines if a class can be accessed from the lookup context defined by this {@code Lookup} object. The
974 * static initializer of the class is not run.
975 * <p>
976 * The lookup context here is determined by the {@linkplain #lookupClass() lookup class} and the
977 * {@linkplain #lookupModes() lookup modes}.
978 *
979 * @param targetClass the class to be access-checked
980 *
981 * @return the class that has been access-checked
982 *
983 * @throws IllegalAccessException if the class is not accessible from the lookup class, using the allowed access
984 * modes.
985 * @exception SecurityException if a security manager is present and it
986 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
987 * @since 9
988 */
989 public Class<?> accessClass(Class<?> targetClass) throws IllegalAccessException {
990 if (!VerifyAccess.isClassAccessible(targetClass, lookupClass, allowedModes)) {
991 throw new MemberName(targetClass).makeAccessException("access violation", this);
992 }
993 checkSecurityManager(targetClass, null);
994 return targetClass;
995 }
996
997 /**
|