home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1998 February / VPR9802A.ISO / APP_DEMO / VC / MAIN.BIN / Field.java < prev    next >
Text File  |  1997-10-27  |  17KB  |  444 lines

  1. /*
  2.  * @(#)Field.java    1.9 97/02/10
  3.  * 
  4.  * Copyright (c) 1995, 1996 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  * CopyrightVersion 1.1_beta
  20.  * 
  21.  */
  22.  
  23. package java.lang.reflect;
  24.  
  25. /**
  26.  * A Field provides information about, and dynamic access to, a
  27.  * single field of a class or an interface.  The reflected field may
  28.  * be a class (static) field or an instance field.
  29.  *
  30.  * <p>A Field permits widening conversions to occur during a get or
  31.  * set access operation, but throws an IllegalArgumentException if a
  32.  * narrowing conversion would occur.
  33.  *
  34.  * @see Member
  35.  * @see java.lang.Class
  36.  * @see java.lang.Class#getFields()
  37.  * @see java.lang.Class#getField()
  38.  * @see java.lang.Class#getDeclaredFields()
  39.  * @see java.lang.Class#getDeclaredField()
  40.  *
  41.  * @author Nakul Saraiya
  42.  */
  43. public final
  44. class Field implements Member {
  45.  
  46.     private Class        clazz;
  47.     private int            slot;
  48.     private String        name;
  49.     private Class        type;
  50.  
  51.     /**
  52.      * Constructor.  Only the Java Virtual Machine may construct a Field.
  53.      */
  54.     private Field() {}
  55.  
  56.     /**
  57.      * Returns the Class object representing the class or interface
  58.      * that declares the field represented by this Field object.
  59.      */
  60.     public Class getDeclaringClass() {
  61.     return clazz;
  62.     }
  63.  
  64.     /**
  65.      * Returns the name of the field represented by this Field object.
  66.      */
  67.     public String getName() {
  68.     return name;
  69.     }
  70.  
  71.     /**
  72.      * Returns the Java language modifiers for the field represented
  73.      * by this Field object, as an integer. The Modifier class should
  74.      * be used to decode the modifiers.
  75.      *
  76.      * @see Modifier
  77.      */
  78.     public native int getModifiers();
  79.  
  80.     /**
  81.      * Returns a Class object that identifies the declared type for
  82.      * the field represented by this Field object.
  83.      */
  84.     public Class getType() {
  85.     return type;
  86.     }
  87.  
  88.     /**
  89.      * Compares this Field against the specified object.  Returns
  90.      * true if the objects are the same.  Two Fields are the same if
  91.      * they were declared by the same class and have the same name
  92.      * and type.
  93.      */
  94.     public boolean equals(Object obj) {
  95.     if (obj != null && obj instanceof Field) {
  96.         Field other = (Field)obj;
  97.         return (getDeclaringClass() == other.getDeclaringClass())
  98.         && (getName().equals(other.getName()))
  99.         && (getType() == other.getType());
  100.     }
  101.     return false;
  102.     }
  103.  
  104.     /**
  105.      * Returns a hashcode for this Field.  This is computed as the
  106.      * exclusive-or of the hashcodes for the underlying field's
  107.      * declaring class name and its name.
  108.      */
  109.     public int hashCode() {
  110.     return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
  111.     }
  112.  
  113.     /**
  114.      * Return a string describing this Field.  The format is
  115.      * the access modifiers for the field, if any, followed
  116.      * by the field type, followed by a space, followed by
  117.      * the fully-qualified name of the class declaring the field,
  118.      * followed by a period, followed by the name of the field.
  119.      * For example:
  120.      * <pre>
  121.      *    public static final int java.lang.Thread.MIN_PRIORITY
  122.      *    private int java.io.FileDescriptor.fd
  123.      * </pre>
  124.      *
  125.      * <p>The modifiers are placed in canonical order as specified by
  126.      * "The Java Language Specification".  This is <tt>public</tt>,
  127.      * <tt>protected</tt> or <tt>private</tt> first, and then other
  128.      * modifiers in the following order: <tt>static</tt>, <tt>final</tt>,
  129.      * <tt>transient</tt>, <tt>volatile</tt>.
  130.      */
  131.     public String toString() {
  132.     int mod = getModifiers();
  133.     return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
  134.         + getTypeName(getType()) + " "
  135.         + getTypeName(getDeclaringClass()) + "."
  136.         + getName());
  137.     }
  138.  
  139.     /**
  140.      * Returns the value of the field represented by this Field, on
  141.      * the specified object. The value is automatically wrapped in an
  142.      * object if it has a primitive type.
  143.      *
  144.      * <p>The underlying field's value is obtained as follows:
  145.      *
  146.      * <p>If the underlying field is a static field, the object argument
  147.      * is ignored; it may be null.
  148.      *
  149.      * <p>Otherwise, the underlying field is an instance field.  If the
  150.      * specified object argument is null, the method throws a
  151.      * NullPointerException. If the specified object is not an
  152.      * instance of the class or interface declaring the underlying
  153.      * field, the method throws an IllegalArgumentException.
  154.      *
  155.      * <p>If this Field object enforces Java language access control, and
  156.      * the underlying field is inaccessible, the method throws an
  157.      * IllegalAccessException.
  158.      *
  159.      * <p>Otherwise, the value is retrieved from the underlying instance
  160.      * or static field.  If the field has a primitive type, the value
  161.      * is wrapped in an object before being returned, otherwise it is
  162.      * returned as is.
  163.      *
  164.      * @exception IllegalAccessException    if the underlying constructor
  165.      *              is inaccessible.
  166.      * @exception IllegalArgumentException  if the specified object is not an
  167.      *              instance of the class or interface declaring the underlying
  168.      *              field.
  169.      * @exception NullPointerException      if the specified object is null.
  170.      */
  171.     public native Object get(Object obj)
  172.     throws IllegalArgumentException, IllegalAccessException;
  173.  
  174.     /**
  175.      * Get the value of a field as a boolean on specified object.
  176.      *
  177.      * @exception IllegalAccessException    if the underlying constructor
  178.      *              is inaccessible.
  179.      * @exception IllegalArgumentException  if the field value cannot be
  180.      *              converted to the return type by a widening conversion.
  181.      * @see       Field#get
  182.      */
  183.     public native boolean getBoolean(Object obj)
  184.     throws IllegalArgumentException, IllegalAccessException;
  185.  
  186.     /**
  187.      * Get the value of a field as a byte on specified object.
  188.      *
  189.      * @exception IllegalAccessException    if the underlying constructor
  190.      *              is inaccessible.
  191.      * @exception IllegalArgumentException  if the field value cannot be
  192.      *              converted to the return type by a widening conversion.
  193.      * @see       Field#get
  194.      */
  195.     public native byte getByte(Object obj)
  196.     throws IllegalArgumentException, IllegalAccessException;
  197.  
  198.     /**
  199.      * Get the value of a field as a char on specified object.
  200.      *
  201.      * @exception IllegalAccessException    if the underlying constructor
  202.      *              is inaccessible.
  203.      * @exception IllegalArgumentException  if the field value cannot be
  204.      *              converted to the return type by a widening conversion.
  205.      * @see       Field#get
  206.      */
  207.     public native char getChar(Object obj)
  208.     throws IllegalArgumentException, IllegalAccessException;
  209.  
  210.     /**
  211.      * Get the value of a field as a short on specified object.
  212.      *
  213.      * @exception IllegalAccessException    if the underlying constructor
  214.      *              is inaccessible.
  215.      * @exception IllegalArgumentException  if the field value cannot be
  216.      *              converted to the return type by a widening conversion.
  217.      * @see       Field#get
  218.      */
  219.     public native short getShort(Object obj)
  220.     throws IllegalArgumentException, IllegalAccessException;
  221.  
  222.     /**
  223.      * Get the value of a field as a int on specified object.
  224.      *
  225.      * @exception IllegalAccessException    if the underlying constructor
  226.      *              is inaccessible.
  227.      * @exception IllegalArgumentException  if the field value cannot be
  228.      *              converted to the return type by a widening conversion.
  229.      * @see       Field#get
  230.      */
  231.     public native int getInt(Object obj)
  232.     throws IllegalArgumentException, IllegalAccessException;
  233.  
  234.     /**
  235.      * Get the value of a field as a long on specified object.
  236.      *
  237.      * @exception IllegalAccessException    if the underlying constructor
  238.      *              is inaccessible.
  239.      * @exception IllegalArgumentException  if the field value cannot be
  240.      *              converted to the return type by a widening conversion.
  241.      * @see       Field#get
  242.      */
  243.     public native long getLong(Object obj)
  244.     throws IllegalArgumentException, IllegalAccessException;
  245.  
  246.     /**
  247.      * Get the value of a field as a float on specified object.
  248.      *
  249.      * @exception IllegalAccessException    if the underlying constructor
  250.      *              is inaccessible.
  251.      * @exception IllegalArgumentException  if the field value cannot be
  252.      *              converted to the return type by a widening conversion.
  253.      * @see       Field#get
  254.      */
  255.     public native float getFloat(Object obj)
  256.     throws IllegalArgumentException, IllegalAccessException;
  257.  
  258.     /**
  259.      * Get the value of a field as a double on specified object.
  260.      *
  261.      * @exception IllegalAccessException    if the underlying constructor
  262.      *              is inaccessible.
  263.      * @exception IllegalArgumentException  if the field value cannot be
  264.      *              converted to the return type by a widening conversion.
  265.      * @see       Field#get
  266.      */
  267.     public native double getDouble(Object obj)
  268.     throws IllegalArgumentException, IllegalAccessException;
  269.  
  270.     /**
  271.      * Sets the field represented by this Field object on the
  272.      * specified object argument to the specified new value. The new
  273.      * value is automatically unwrapped if the underlying field has a
  274.      * primitive type.
  275.      *
  276.      * <p>The operation proceeds as follows:
  277.      *
  278.      * <p>If the underlying field is static, the object argument is
  279.      * ignored; it may be null.
  280.      *
  281.      * <p>Otherwise the underlying field is an instance field.  If the
  282.      * specified object argument is null, the method throws a
  283.      * NullPointerException.  If the specified object argument is not
  284.      * an instance of the class or interface declaring the underlying
  285.      * field, the method throws an IllegalArgumentException.
  286.      *
  287.      * <p>If this Field object enforces Java language access control, and
  288.      * the underlying field is inaccessible, the method throws an
  289.      * IllegalAccessException.
  290.      *
  291.      * <p>If the underlying field is final, the method throws an
  292.      * IllegalAccessException.
  293.      *
  294.      * <p>If the underlying field is of a primitive type, an unwrapping
  295.      * conversion is attempted to convert the new value to a value of
  296.      * a primitive type.  If this attempt fails, the method throws an
  297.      * IllegalArgumentException.
  298.      *
  299.      * <p>If, after possible unwrapping, the new value cannot be
  300.      * converted to the type of the underlying field by an identity or
  301.      * widening conversion, the method throws an
  302.      * IllegalArgumentException.
  303.      *
  304.      * <p>The field is set to the possibly unwrapped and widened new value.
  305.      *
  306.      * @exception IllegalAccessException    if the underlying constructor
  307.      *              is inaccessible.
  308.      * @exception IllegalArgumentException  if the specified object is not an
  309.      *              instance of the class or interface declaring the underlying
  310.      *              field, or if an unwrapping conversion fails.
  311.      * @exception NullPointerException      if the specified object is null.
  312.      */
  313.     public native void set(Object obj, Object value)
  314.     throws IllegalArgumentException, IllegalAccessException;
  315.  
  316.     /**
  317.      * Set the value of a field as a boolean on specified object.
  318.      *
  319.      * @exception IllegalAccessException    if the underlying constructor
  320.      *              is inaccessible.
  321.      * @exception IllegalArgumentException  if the specified object is not an
  322.      *              instance of the class or interface declaring the underlying
  323.      *              field, or if an unwrapping conversion fails.
  324.      * @see       Field#set
  325.      */
  326.     public native void setBoolean(Object obj, boolean z)
  327.     throws IllegalArgumentException, IllegalAccessException;
  328.  
  329.     /**
  330.      * Set the value of a field as a byte on specified object.
  331.      *
  332.      * @exception IllegalAccessException    if the underlying constructor
  333.      *              is inaccessible.
  334.      * @exception IllegalArgumentException  if the specified object is not an
  335.      *              instance of the class or interface declaring the underlying
  336.      *              field, or if an unwrapping conversion fails.
  337.      * @see       Field#set
  338.      */
  339.     public native void setByte(Object obj, byte b)
  340.     throws IllegalArgumentException, IllegalAccessException;
  341.  
  342.     /**
  343.      * Set the value of a field as a char on specified object.
  344.      *
  345.      * @exception IllegalAccessException    if the underlying constructor
  346.      *              is inaccessible.
  347.      * @exception IllegalArgumentException  if the specified object is not an
  348.      *              instance of the class or interface declaring the underlying
  349.      *              field, or if an unwrapping conversion fails.
  350.      * @see       Field#set
  351.      */
  352.     public native void setChar(Object obj, char c)
  353.     throws IllegalArgumentException, IllegalAccessException;
  354.  
  355.     /**
  356.      * Set the value of a field as a short on specified object.
  357.      *
  358.      * @exception IllegalAccessException    if the underlying constructor
  359.      *              is inaccessible.
  360.      * @exception IllegalArgumentException  if the specified object is not an
  361.      *              instance of the class or interface declaring the underlying
  362.      *              field, or if an unwrapping conversion fails.
  363.      * @see       Field#set
  364.      */
  365.     public native void setShort(Object obj, short s)
  366.     throws IllegalArgumentException, IllegalAccessException;
  367.  
  368.     /**
  369.      * Set the value of a field as an int on specified object.
  370.      *
  371.      * @exception IllegalAccessException    if the underlying constructor
  372.      *              is inaccessible.
  373.      * @exception IllegalArgumentException  if the specified object is not an
  374.      *              instance of the class or interface declaring the underlying
  375.      *              field, or if an unwrapping conversion fails.
  376.      * @see       Field#set
  377.      */
  378.     public native void setInt(Object obj, int i)
  379.     throws IllegalArgumentException, IllegalAccessException;
  380.  
  381.     /**
  382.      * Set the value of a field as a long on specified object.
  383.      *
  384.      * @exception IllegalAccessException    if the underlying constructor
  385.      *              is inaccessible.
  386.      * @exception IllegalArgumentException  if the specified object is not an
  387.      *              instance of the class or interface declaring the underlying
  388.      *              field, or if an unwrapping conversion fails.
  389.      * @see       Field#set
  390.      */
  391.     public native void setLong(Object obj, long l)
  392.     throws IllegalArgumentException, IllegalAccessException;
  393.  
  394.     /**
  395.      * Set the value of a field as a float on specified object.
  396.      *
  397.      * @exception IllegalAccessException    if the underlying constructor
  398.      *              is inaccessible.
  399.      * @exception IllegalArgumentException  if the specified object is not an
  400.      *              instance of the class or interface declaring the underlying
  401.      *              field, or if an unwrapping conversion fails.
  402.      * @see       Field#set
  403.      */
  404.     public native void setFloat(Object obj, float f)
  405.     throws IllegalArgumentException, IllegalAccessException;
  406.  
  407.     /**
  408.      * Set the value of a field as a double on specified object.
  409.      *
  410.      * @exception IllegalAccessException    if the underlying constructor
  411.      *              is inaccessible.
  412.      * @exception IllegalArgumentException  if the specified object is not an
  413.      *              instance of the class or interface declaring the underlying
  414.      *              field, or if an unwrapping conversion fails.
  415.      * @see       Field#set
  416.      */
  417.     public native void setDouble(Object obj, double d)
  418.     throws IllegalArgumentException, IllegalAccessException;
  419.  
  420.     /*
  421.      * Utility routine to paper over array type names
  422.      */
  423.     static String getTypeName(Class type) {
  424.     if (type.isArray()) {
  425.         try {
  426.         Class cl = type;
  427.         int dimensions = 0;
  428.         while (cl.isArray()) {
  429.             dimensions++;
  430.             cl = cl.getComponentType();
  431.         }
  432.         StringBuffer sb = new StringBuffer();
  433.         sb.append(cl.getName());
  434.         for (int i = 0; i < dimensions; i++) {
  435.             sb.append("[]");
  436.         }
  437.         return sb.toString();
  438.         } catch (Throwable e) { /*FALLTHRU*/ }
  439.     }
  440.     return type.getName();
  441.     }
  442.  
  443. }
  444.