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.generic;
19  
20  import org.apache.bcel.Const;
21  
22  /**
23   * Denotes array type, such as int[][]
24   *
25   */
26  public final class ArrayType extends ReferenceType {
27  
28      private int dimensions;
29      private Type basicType;
30  
31  
32      /**
33       * Convenience constructor for array type, e.g. int[]
34       *
35       * @param type array type, e.g. T_INT
36       */
37      public ArrayType(final byte type, final int dimensions) {
38          this(BasicType.getType(type), dimensions);
39      }
40  
41  
42      /**
43       * Convenience constructor for reference array type, e.g. Object[]
44       *
45       * @param class_name complete name of class (java.lang.String, e.g.)
46       */
47      public ArrayType(final String class_name, final int dimensions) {
48          this(ObjectType.getInstance(class_name), dimensions);
49      }
50  
51  
52      /**
53       * Constructor for array of given type
54       *
55       * @param type type of array (may be an array itself)
56       */
57      public ArrayType(final Type type, final int dimensions) {
58          super(Const.T_ARRAY, "<dummy>");
59          if ((dimensions < 1) || (dimensions > Const.MAX_BYTE)) {
60              throw new ClassGenException("Invalid number of dimensions: " + dimensions);
61          }
62          switch (type.getType()) {
63              case Const.T_ARRAY:
64                  final ArrayType/../../../org/apache/bcel/generic/ArrayType.html#ArrayType">ArrayType array = (ArrayType) type;
65                  this.dimensions = dimensions + array.dimensions;
66                  basicType = array.basicType;
67                  break;
68              case Const.T_VOID:
69                  throw new ClassGenException("Invalid type: void[]");
70              default: // Basic type or reference
71                  this.dimensions = dimensions;
72                  basicType = type;
73                  break;
74          }
75          final StringBuilder buf = new StringBuilder();
76          for (int i = 0; i < this.dimensions; i++) {
77              buf.append('[');
78          }
79          buf.append(basicType.getSignature());
80          super.setSignature(buf.toString());
81      }
82  
83  
84      /**
85       * @return basic type of array, i.e., for int[][][] the basic type is int
86       */
87      public Type getBasicType() {
88          return basicType;
89      }
90  
91  
92      /**
93       * @return element type of array, i.e., for int[][][] the element type is int[][]
94       */
95      public Type getElementType() {
96          if (dimensions == 1) {
97              return basicType;
98          }
99          return new ArrayType(basicType, dimensions - 1);
100     }
101 
102 
103     /** @return number of dimensions of array
104      */
105     public int getDimensions() {
106         return dimensions;
107     }
108 
109 
110     /** @return a hash code value for the object.
111      */
112     @Override
113     public int hashCode() {
114         return basicType.hashCode() ^ dimensions;
115     }
116 
117 
118     /** @return true if both type objects refer to the same array type.
119      */
120     @Override
121     public boolean equals( final Object _type ) {
122         if (_type instanceof ArrayType) {
123             final ArrayType/../../../org/apache/bcel/generic/ArrayType.html#ArrayType">ArrayType array = (ArrayType) _type;
124             return (array.dimensions == dimensions) && array.basicType.equals(basicType);
125         }
126         return false;
127     }
128 }