405 * All access checks start from a {@code Lookup} object, which
406 * compares its recorded lookup class against all requests to
407 * create method handles.
408 * A single {@code Lookup} object can be used to create any number
409 * of access-checked method handles, all checked against a single
410 * lookup class.
411 * <p>
412 * A {@code Lookup} object can be shared with other trusted code,
413 * such as a metaobject protocol.
414 * A shared {@code Lookup} object delegates the capability
415 * to create method handles on private members of the lookup class.
416 * Even if privileged code uses the {@code Lookup} object,
417 * the access checking is confined to the privileges of the
418 * original lookup class.
419 * <p>
420 * A lookup can fail, because
421 * the containing class is not accessible to the lookup class, or
422 * because the desired class member is missing, or because the
423 * desired class member is not accessible to the lookup class, or
424 * because the lookup object is not trusted enough to access the member.
425 * In any of these cases, a {@code ReflectiveOperationException} will be
426 * thrown from the attempted lookup. The exact class will be one of
427 * the following:
428 * <ul>
429 * <li>NoSuchMethodException — if a method is requested but does not exist
430 * <li>NoSuchFieldException — if a field is requested but does not exist
431 * <li>IllegalAccessException — if the member exists but an access check fails
432 * </ul>
433 * <p>
434 * In general, the conditions under which a method handle may be
435 * looked up for a method {@code M} are no more restrictive than the conditions
436 * under which the lookup class could have compiled, verified, and resolved a call to {@code M}.
437 * Where the JVM would raise exceptions like {@code NoSuchMethodError},
438 * a method handle lookup will generally raise a corresponding
439 * checked exception, such as {@code NoSuchMethodException}.
440 * And the effect of invoking the method handle resulting from the lookup
441 * is <a href="MethodHandles.Lookup.html#equiv">exactly equivalent</a>
442 * to executing the compiled, verified, and resolved call to {@code M}.
443 * The same point is true of fields and constructors.
444 * <p style="font-size:smaller;">
1421 * @see #findVarHandle(Class, String, Class)
1422 */
1423 public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
1424 MemberName field = resolveOrFail(REF_getField, refc, name, type);
1425 return getDirectField(REF_getField, refc, field);
1426 }
1427
1428 /**
1429 * Produces a method handle giving write access to a non-static field.
1430 * The type of the method handle will have a void return type.
1431 * The method handle will take two arguments, the instance containing
1432 * the field, and the value to be stored.
1433 * The second argument will be of the field's value type.
1434 * Access checking is performed immediately on behalf of the lookup class.
1435 * @param refc the class or interface from which the method is accessed
1436 * @param name the field's name
1437 * @param type the field's type
1438 * @return a method handle which can store values into the field
1439 * @throws NoSuchFieldException if the field does not exist
1440 * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
1441 * @exception SecurityException if a security manager is present and it
1442 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1443 * @throws NullPointerException if any argument is null
1444 * @see #findVarHandle(Class, String, Class)
1445 */
1446 public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
1447 MemberName field = resolveOrFail(REF_putField, refc, name, type);
1448 return getDirectField(REF_putField, refc, field);
1449 }
1450
1451 /**
1452 * Produces a VarHandle giving access to a non-static field {@code name}
1453 * of type {@code type} declared in a class of type {@code recv}.
1454 * The VarHandle's variable type is {@code type} and it has one
1455 * coordinate type, {@code recv}.
1456 * <p>
1457 * Access checking is performed immediately on behalf of the lookup
1458 * class.
1459 * <p>
1460 * Certain access modes of the returned VarHandle are unsupported under
1544 public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
1545 MemberName field = resolveOrFail(REF_getStatic, refc, name, type);
1546 return getDirectField(REF_getStatic, refc, field);
1547 }
1548
1549 /**
1550 * Produces a method handle giving write access to a static field.
1551 * The type of the method handle will have a void return type.
1552 * The method handle will take a single
1553 * argument, of the field's value type, the value to be stored.
1554 * Access checking is performed immediately on behalf of the lookup class.
1555 * <p>
1556 * If the returned method handle is invoked, the field's class will
1557 * be initialized, if it has not already been initialized.
1558 * @param refc the class or interface from which the method is accessed
1559 * @param name the field's name
1560 * @param type the field's type
1561 * @return a method handle which can store values into the field
1562 * @throws NoSuchFieldException if the field does not exist
1563 * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
1564 * @exception SecurityException if a security manager is present and it
1565 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1566 * @throws NullPointerException if any argument is null
1567 */
1568 public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
1569 MemberName field = resolveOrFail(REF_putStatic, refc, name, type);
1570 return getDirectField(REF_putStatic, refc, field);
1571 }
1572
1573 /**
1574 * Produces a VarHandle giving access to a static field {@code name} of
1575 * type {@code type} declared in a class of type {@code decl}.
1576 * The VarHandle's variable type is {@code type} and it has no
1577 * coordinate types.
1578 * <p>
1579 * Access checking is performed immediately on behalf of the lookup
1580 * class.
1581 * <p>
1582 * If the returned VarHandle is operated on, the declaring class will be
1583 * initialized, if it has not already been initialized.
1823 * be initialized, if it has not already been initialized.
1824 * @param c the reflected constructor
1825 * @return a method handle which can invoke the reflected constructor
1826 * @throws IllegalAccessException if access checking fails
1827 * or if the method's variable arity modifier bit
1828 * is set and {@code asVarargsCollector} fails
1829 * @throws NullPointerException if the argument is null
1830 */
1831 public MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException {
1832 MemberName ctor = new MemberName(c);
1833 assert(ctor.isConstructor());
1834 @SuppressWarnings("deprecation")
1835 Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this;
1836 return lookup.getDirectConstructorNoSecurityManager(ctor.getDeclaringClass(), ctor);
1837 }
1838
1839 /**
1840 * Produces a method handle giving read access to a reflected field.
1841 * The type of the method handle will have a return type of the field's
1842 * value type.
1843 * If the field is static, the method handle will take no arguments.
1844 * Otherwise, its single argument will be the instance containing
1845 * the field.
1846 * If the field's {@code accessible} flag is not set,
1847 * access checking is performed immediately on behalf of the lookup class.
1848 * <p>
1849 * If the field is static, and
1850 * if the returned method handle is invoked, the field's class will
1851 * be initialized, if it has not already been initialized.
1852 * @param f the reflected field
1853 * @return a method handle which can load values from the reflected field
1854 * @throws IllegalAccessException if access checking fails
1855 * @throws NullPointerException if the argument is null
1856 */
1857 public MethodHandle unreflectGetter(Field f) throws IllegalAccessException {
1858 return unreflectField(f, false);
1859 }
1860 private MethodHandle unreflectField(Field f, boolean isSetter) throws IllegalAccessException {
1861 MemberName field = new MemberName(f, isSetter);
1862 assert(isSetter
1863 ? MethodHandleNatives.refKindIsSetter(field.getReferenceKind())
1864 : MethodHandleNatives.refKindIsGetter(field.getReferenceKind()));
1865 @SuppressWarnings("deprecation")
1866 Lookup lookup = f.isAccessible() ? IMPL_LOOKUP : this;
1867 return lookup.getDirectFieldNoSecurityManager(field.getReferenceKind(), f.getDeclaringClass(), field);
1868 }
1869
1870 /**
1871 * Produces a method handle giving write access to a reflected field.
1872 * The type of the method handle will have a void return type.
1873 * If the field is static, the method handle will take a single
1874 * argument, of the field's value type, the value to be stored.
1875 * Otherwise, the two arguments will be the instance containing
1876 * the field, and the value to be stored.
1877 * If the field's {@code accessible} flag is not set,
1878 * access checking is performed immediately on behalf of the lookup class.
1879 * <p>
1880 * If the field is static, and
1881 * if the returned method handle is invoked, the field's class will
1882 * be initialized, if it has not already been initialized.
1883 * @param f the reflected field
1884 * @return a method handle which can store values into the reflected field
1885 * @throws IllegalAccessException if access checking fails
1886 * @throws NullPointerException if the argument is null
1887 */
1888 public MethodHandle unreflectSetter(Field f) throws IllegalAccessException {
1889 return unreflectField(f, true);
1890 }
1891
1892 /**
1893 * Produces a VarHandle giving access to a reflected field {@code f}
1894 * of type {@code T} declared in a class of type {@code R}.
1895 * The VarHandle's variable type is {@code T}.
1896 * If the field is non-static the VarHandle has one coordinate type,
1897 * {@code R}. Otherwise, the field is static, and the VarHandle has no
1898 * coordinate types.
1899 * <p>
1900 * Access checking is performed immediately on behalf of the lookup
1901 * class, regardless of the value of the field's {@code accessible}
1902 * flag.
1903 * <p>
1904 * If the field is static, and if the returned VarHandle is operated
1905 * on, the field's declaring class will be initialized, if it has not
|
405 * All access checks start from a {@code Lookup} object, which
406 * compares its recorded lookup class against all requests to
407 * create method handles.
408 * A single {@code Lookup} object can be used to create any number
409 * of access-checked method handles, all checked against a single
410 * lookup class.
411 * <p>
412 * A {@code Lookup} object can be shared with other trusted code,
413 * such as a metaobject protocol.
414 * A shared {@code Lookup} object delegates the capability
415 * to create method handles on private members of the lookup class.
416 * Even if privileged code uses the {@code Lookup} object,
417 * the access checking is confined to the privileges of the
418 * original lookup class.
419 * <p>
420 * A lookup can fail, because
421 * the containing class is not accessible to the lookup class, or
422 * because the desired class member is missing, or because the
423 * desired class member is not accessible to the lookup class, or
424 * because the lookup object is not trusted enough to access the member.
425 * In the case of a field setter function on a {@code final} field,
426 * finality enforcement is treated as a kind of access control,
427 * and the lookup will fail, except in special cases of
428 * {@link Lookup#unreflectSetter Lookup.unreflectSetter}.
429 * In any of these cases, a {@code ReflectiveOperationException} will be
430 * thrown from the attempted lookup. The exact class will be one of
431 * the following:
432 * <ul>
433 * <li>NoSuchMethodException — if a method is requested but does not exist
434 * <li>NoSuchFieldException — if a field is requested but does not exist
435 * <li>IllegalAccessException — if the member exists but an access check fails
436 * </ul>
437 * <p>
438 * In general, the conditions under which a method handle may be
439 * looked up for a method {@code M} are no more restrictive than the conditions
440 * under which the lookup class could have compiled, verified, and resolved a call to {@code M}.
441 * Where the JVM would raise exceptions like {@code NoSuchMethodError},
442 * a method handle lookup will generally raise a corresponding
443 * checked exception, such as {@code NoSuchMethodException}.
444 * And the effect of invoking the method handle resulting from the lookup
445 * is <a href="MethodHandles.Lookup.html#equiv">exactly equivalent</a>
446 * to executing the compiled, verified, and resolved call to {@code M}.
447 * The same point is true of fields and constructors.
448 * <p style="font-size:smaller;">
1425 * @see #findVarHandle(Class, String, Class)
1426 */
1427 public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
1428 MemberName field = resolveOrFail(REF_getField, refc, name, type);
1429 return getDirectField(REF_getField, refc, field);
1430 }
1431
1432 /**
1433 * Produces a method handle giving write access to a non-static field.
1434 * The type of the method handle will have a void return type.
1435 * The method handle will take two arguments, the instance containing
1436 * the field, and the value to be stored.
1437 * The second argument will be of the field's value type.
1438 * Access checking is performed immediately on behalf of the lookup class.
1439 * @param refc the class or interface from which the method is accessed
1440 * @param name the field's name
1441 * @param type the field's type
1442 * @return a method handle which can store values into the field
1443 * @throws NoSuchFieldException if the field does not exist
1444 * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
1445 * or {@code final}
1446 * @exception SecurityException if a security manager is present and it
1447 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1448 * @throws NullPointerException if any argument is null
1449 * @see #findVarHandle(Class, String, Class)
1450 */
1451 public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
1452 MemberName field = resolveOrFail(REF_putField, refc, name, type);
1453 return getDirectField(REF_putField, refc, field);
1454 }
1455
1456 /**
1457 * Produces a VarHandle giving access to a non-static field {@code name}
1458 * of type {@code type} declared in a class of type {@code recv}.
1459 * The VarHandle's variable type is {@code type} and it has one
1460 * coordinate type, {@code recv}.
1461 * <p>
1462 * Access checking is performed immediately on behalf of the lookup
1463 * class.
1464 * <p>
1465 * Certain access modes of the returned VarHandle are unsupported under
1549 public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
1550 MemberName field = resolveOrFail(REF_getStatic, refc, name, type);
1551 return getDirectField(REF_getStatic, refc, field);
1552 }
1553
1554 /**
1555 * Produces a method handle giving write access to a static field.
1556 * The type of the method handle will have a void return type.
1557 * The method handle will take a single
1558 * argument, of the field's value type, the value to be stored.
1559 * Access checking is performed immediately on behalf of the lookup class.
1560 * <p>
1561 * If the returned method handle is invoked, the field's class will
1562 * be initialized, if it has not already been initialized.
1563 * @param refc the class or interface from which the method is accessed
1564 * @param name the field's name
1565 * @param type the field's type
1566 * @return a method handle which can store values into the field
1567 * @throws NoSuchFieldException if the field does not exist
1568 * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
1569 * or is {@code final}
1570 * @exception SecurityException if a security manager is present and it
1571 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1572 * @throws NullPointerException if any argument is null
1573 */
1574 public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
1575 MemberName field = resolveOrFail(REF_putStatic, refc, name, type);
1576 return getDirectField(REF_putStatic, refc, field);
1577 }
1578
1579 /**
1580 * Produces a VarHandle giving access to a static field {@code name} of
1581 * type {@code type} declared in a class of type {@code decl}.
1582 * The VarHandle's variable type is {@code type} and it has no
1583 * coordinate types.
1584 * <p>
1585 * Access checking is performed immediately on behalf of the lookup
1586 * class.
1587 * <p>
1588 * If the returned VarHandle is operated on, the declaring class will be
1589 * initialized, if it has not already been initialized.
1829 * be initialized, if it has not already been initialized.
1830 * @param c the reflected constructor
1831 * @return a method handle which can invoke the reflected constructor
1832 * @throws IllegalAccessException if access checking fails
1833 * or if the method's variable arity modifier bit
1834 * is set and {@code asVarargsCollector} fails
1835 * @throws NullPointerException if the argument is null
1836 */
1837 public MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException {
1838 MemberName ctor = new MemberName(c);
1839 assert(ctor.isConstructor());
1840 @SuppressWarnings("deprecation")
1841 Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this;
1842 return lookup.getDirectConstructorNoSecurityManager(ctor.getDeclaringClass(), ctor);
1843 }
1844
1845 /**
1846 * Produces a method handle giving read access to a reflected field.
1847 * The type of the method handle will have a return type of the field's
1848 * value type.
1849 * If the field is {@code static}, the method handle will take no arguments.
1850 * Otherwise, its single argument will be the instance containing
1851 * the field.
1852 * If the {@code Field} object's {@code accessible} flag is not set,
1853 * access checking is performed immediately on behalf of the lookup class.
1854 * <p>
1855 * If the field is static, and
1856 * if the returned method handle is invoked, the field's class will
1857 * be initialized, if it has not already been initialized.
1858 * @param f the reflected field
1859 * @return a method handle which can load values from the reflected field
1860 * @throws IllegalAccessException if access checking fails
1861 * @throws NullPointerException if the argument is null
1862 */
1863 public MethodHandle unreflectGetter(Field f) throws IllegalAccessException {
1864 return unreflectField(f, false);
1865 }
1866 private MethodHandle unreflectField(Field f, boolean isSetter) throws IllegalAccessException {
1867 MemberName field = new MemberName(f, isSetter);
1868 assert(isSetter
1869 ? MethodHandleNatives.refKindIsSetter(field.getReferenceKind())
1870 : MethodHandleNatives.refKindIsGetter(field.getReferenceKind()));
1871 if (isSetter && field.isStatic() && field.isFinal()) {
1872 throw field.makeAccessException("static final field has no write access", this);
1873 }
1874 @SuppressWarnings("deprecation")
1875 Lookup lookup = f.isAccessible() ? IMPL_LOOKUP : this;
1876 return lookup.getDirectFieldNoSecurityManager(field.getReferenceKind(), f.getDeclaringClass(), field);
1877 }
1878
1879 /**
1880 * Produces a method handle giving write access to a reflected field.
1881 * The type of the method handle will have a void return type.
1882 * If the field is {@code static}, the method handle will take a single
1883 * argument, of the field's value type, the value to be stored.
1884 * Otherwise, the two arguments will be the instance containing
1885 * the field, and the value to be stored.
1886 * If the {@code Field} object's {@code accessible} flag is not set,
1887 * access checking is performed immediately on behalf of the lookup class.
1888 * <p>
1889 * If the field is {@code final}, write access will not be
1890 * allowed and access checking will fail, except under certain
1891 * narrow circumstances documented for {@link Field#set Field.set}.
1892 * A method handle is returned only if a corresponding call to
1893 * the {@code Field} object's {@code set} method could return
1894 * normally. In particular, fields which are both {@code static}
1895 * and {@code final} may never be set.
1896 * <p>
1897 * If the field is {@code static}, and
1898 * if the returned method handle is invoked, the field's class will
1899 * be initialized, if it has not already been initialized.
1900 * @param f the reflected field
1901 * @return a method handle which can store values into the reflected field
1902 * @throws IllegalAccessException if access checking fails,
1903 * or if the field is {@code final} and write access
1904 * is not enabled on the {@code Field} object
1905 * @throws NullPointerException if the argument is null
1906 */
1907 public MethodHandle unreflectSetter(Field f) throws IllegalAccessException {
1908 return unreflectField(f, true);
1909 }
1910
1911 /**
1912 * Produces a VarHandle giving access to a reflected field {@code f}
1913 * of type {@code T} declared in a class of type {@code R}.
1914 * The VarHandle's variable type is {@code T}.
1915 * If the field is non-static the VarHandle has one coordinate type,
1916 * {@code R}. Otherwise, the field is static, and the VarHandle has no
1917 * coordinate types.
1918 * <p>
1919 * Access checking is performed immediately on behalf of the lookup
1920 * class, regardless of the value of the field's {@code accessible}
1921 * flag.
1922 * <p>
1923 * If the field is static, and if the returned VarHandle is operated
1924 * on, the field's declaring class will be initialized, if it has not
|