View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   *
17   */
18  package org.apache.bcel.classfile;
19  
20  import java.io.DataInput;
21  import java.io.IOException;
22  
23  import org.apache.bcel.Const;
24  import org.apache.bcel.generic.Type;
25  import org.apache.bcel.util.BCELComparator;
26  
27  /**
28   * This class represents the field info structure, i.e., the representation
29   * for a variable in the class. See JVM specification for details.
30   *
31   * @version $Id: Field.html 1018313 2017-09-18 09:03:04Z britter $
32   */
33  public final class Field extends FieldOrMethod {
34  
35      private static BCELComparator bcelComparator = new BCELComparator() {
36  
37          @Override
38          public boolean equals( final Object o1, final Object o2 ) {
39              final Field THIS = (Field) o1;
40              final Field THAT = (Field) o2;
41              return THIS.getName().equals(THAT.getName())
42                      && THIS.getSignature().equals(THAT.getSignature());
43          }
44  
45  
46          @Override
47          public int hashCode( final Object o ) {
48              final Field THIS = (Field) o;
49              return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
50          }
51      };
52  
53  
54      /**
55       * Initialize from another object. Note that both objects use the same
56       * references (shallow copy). Use clone() for a physical copy.
57       */
58      public Field(final Field c) {
59          super(c);
60      }
61  
62  
63      /**
64       * Construct object from file stream.
65       * @param file Input stream
66       */
67      Field(final DataInput file, final ConstantPool constant_pool) throws IOException,
68              ClassFormatException {
69          super(file, constant_pool);
70      }
71  
72  
73      /**
74       * @param access_flags Access rights of field
75       * @param name_index Points to field name in constant pool
76       * @param signature_index Points to encoded signature
77       * @param attributes Collection of attributes
78       * @param constant_pool Array of constants
79       */
80      public Field(final int access_flags, final int name_index, final int signature_index, final Attribute[] attributes,
81              final ConstantPool constant_pool) {
82          super(access_flags, name_index, signature_index, attributes, constant_pool);
83      }
84  
85  
86      /**
87       * Called by objects that are traversing the nodes of the tree implicitely
88       * defined by the contents of a Java class. I.e., the hierarchy of methods,
89       * fields, attributes, etc. spawns a tree of objects.
90       *
91       * @param v Visitor object
92       */
93      @Override
94      public void accept( final Visitor v ) {
95          v.visitField(this);
96      }
97  
98  
99      /**
100      * @return constant value associated with this field (may be null)
101      */
102     public final ConstantValue getConstantValue() {
103         for (final Attribute attribute : super.getAttributes()) {
104             if (attribute.getTag() == Const.ATTR_CONSTANT_VALUE) {
105                 return (ConstantValue) attribute;
106             }
107         }
108         return null;
109     }
110 
111 
112     /**
113      * Return string representation close to declaration format,
114      * `public static final short MAX = 100', e.g..
115      *
116      * @return String representation of field, including the signature.
117      */
118     @Override
119     public final String toString() {
120         String name;
121         String signature;
122         String access; // Short cuts to constant pool
123 
124         // Get names from constant pool
125         access = Utility.accessToString(super.getAccessFlags());
126         access = access.isEmpty() ? "" : (access + " ");
127         signature = Utility.signatureToString(getSignature());
128         name = getName();
129         final StringBuilder buf = new StringBuilder(64); // CHECKSTYLE IGNORE MagicNumber
130         buf.append(access).append(signature).append(" ").append(name);
131         final ConstantValue cv = getConstantValue();
132         if (cv != null) {
133             buf.append(" = ").append(cv);
134         }
135         for (final Attribute attribute : super.getAttributes()) {
136             if (!(attribute instanceof ConstantValue)) {
137                 buf.append(" [").append(attribute).append("]");
138             }
139         }
140         return buf.toString();
141     }
142 
143 
144     /**
145      * @return deep copy of this field
146      */
147     public final Field copy( final ConstantPool _constant_pool ) {
148         return (Field) copy_(_constant_pool);
149     }
150 
151 
152     /**
153      * @return type of field
154      */
155     public Type getType() {
156         return Type.getReturnType(getSignature());
157     }
158 
159 
160     /**
161      * @return Comparison strategy object
162      */
163     public static BCELComparator getComparator() {
164         return bcelComparator;
165     }
166 
167 
168     /**
169      * @param comparator Comparison strategy object
170      */
171     public static void setComparator( final BCELComparator comparator ) {
172         bcelComparator = comparator;
173     }
174 
175 
176     /**
177      * Return value as defined by given BCELComparator strategy.
178      * By default two Field objects are said to be equal when
179      * their names and signatures are equal.
180      *
181      * @see java.lang.Object#equals(java.lang.Object)
182      */
183     @Override
184     public boolean equals( final Object obj ) {
185         return bcelComparator.equals(this, obj);
186     }
187 
188 
189     /**
190      * Return value as defined by given BCELComparator strategy.
191      * By default return the hashcode of the field's name XOR signature.
192      *
193      * @see java.lang.Object#hashCode()
194      */
195     @Override
196     public int hashCode() {
197         return bcelComparator.hashCode(this);
198     }
199 }