Types.java revision 301174b9ed79a73e35d7463f06ae48eb0654c6ca
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package libcore.reflect; 18 19import java.lang.reflect.GenericArrayType; 20import java.lang.reflect.ParameterizedType; 21import java.lang.reflect.Type; 22import java.lang.reflect.TypeVariable; 23import java.util.HashMap; 24import java.util.Map; 25 26public final class Types { 27 private Types() { 28 } 29 30 // Holds a mapping from Java type names to native type codes. 31 private static final Map<Class<?>, String> PRIMITIVE_TO_SIGNATURE; 32 static { 33 PRIMITIVE_TO_SIGNATURE = new HashMap<Class<?>, String>(9); 34 PRIMITIVE_TO_SIGNATURE.put(byte.class, "B"); 35 PRIMITIVE_TO_SIGNATURE.put(char.class, "C"); 36 PRIMITIVE_TO_SIGNATURE.put(short.class, "S"); 37 PRIMITIVE_TO_SIGNATURE.put(int.class, "I"); 38 PRIMITIVE_TO_SIGNATURE.put(long.class, "J"); 39 PRIMITIVE_TO_SIGNATURE.put(float.class, "F"); 40 PRIMITIVE_TO_SIGNATURE.put(double.class, "D"); 41 PRIMITIVE_TO_SIGNATURE.put(void.class, "V"); 42 PRIMITIVE_TO_SIGNATURE.put(boolean.class, "Z"); 43 } 44 45 public static Type[] getClonedTypeArray(ListOfTypes types) { 46 return types.getResolvedTypes().clone(); 47 } 48 49 public static Type getType(Type type) { 50 if (type instanceof ParameterizedTypeImpl) { 51 return ((ParameterizedTypeImpl)type).getResolvedType(); 52 } else { 53 return type; 54 } 55 } 56 57 /** 58 * Returns the internal name of {@code clazz} (also known as the descriptor). 59 */ 60 public static String getSignature(Class<?> clazz) { 61 String primitiveSignature = PRIMITIVE_TO_SIGNATURE.get(clazz); 62 if (primitiveSignature != null) { 63 return primitiveSignature; 64 } else if (clazz.isArray()) { 65 return "[" + getSignature(clazz.getComponentType()); 66 } else { 67 // TODO: this separates packages with '.' rather than '/' 68 return "L" + clazz.getName() + ";"; 69 } 70 } 71 72 /** 73 * Returns the names of {@code types} separated by commas. 74 */ 75 public static String toString(Class<?>[] types) { 76 if (types.length == 0) { 77 return ""; 78 } 79 StringBuilder result = new StringBuilder(); 80 appendTypeName(result, types[0]); 81 for (int i = 1; i < types.length; i++) { 82 result.append(','); 83 appendTypeName(result, types[i]); 84 } 85 return result.toString(); 86 } 87 88 /** 89 * Appends the best {@link #toString} name for {@code c} to {@code out}. 90 * This works around the fact that {@link Class#getName} is lousy for 91 * primitive arrays (it writes "[C" instead of "char[]") and {@link 92 * Class#getCanonicalName()} is lousy for nested classes (it uses a "." 93 * separator rather than a "$" separator). 94 */ 95 public static void appendTypeName(StringBuilder out, Class<?> c) { 96 int dimensions = 0; 97 while (c.isArray()) { 98 c = c.getComponentType(); 99 dimensions++; 100 } 101 out.append(c.getName()); 102 for (int d = 0; d < dimensions; d++) { 103 out.append("[]"); 104 } 105 } 106 107 /** 108 * Appends names of the {@code types} to {@code out} separated by commas. 109 */ 110 public static void appendArrayGenericType(StringBuilder out, Type[] types) { 111 if (types.length == 0) { 112 return; 113 } 114 appendGenericType(out, types[0]); 115 for (int i = 1; i < types.length; i++) { 116 out.append(','); 117 appendGenericType(out, types[i]); 118 } 119 } 120 121 public static void appendGenericType(StringBuilder out, Type type) { 122 if (type instanceof TypeVariable) { 123 out.append(((TypeVariable) type).getName()); 124 } else if (type instanceof ParameterizedType) { 125 out.append(type.toString()); 126 } else if (type instanceof GenericArrayType) { 127 Type simplified = ((GenericArrayType) type).getGenericComponentType(); 128 appendGenericType(out, simplified); 129 out.append("[]"); 130 } else if (type instanceof Class) { 131 Class c = (Class<?>) type; 132 if (c.isArray()){ 133 String as[] = c.getName().split("\\["); 134 int len = as.length-1; 135 if (as[len].length() > 1){ 136 out.append(as[len].substring(1, as[len].length() - 1)); 137 } else { 138 char ch = as[len].charAt(0); 139 if (ch == 'I') { 140 out.append("int"); 141 } else if (ch == 'B') { 142 out.append("byte"); 143 } else if (ch == 'J') { 144 out.append("long"); 145 } else if (ch == 'F') { 146 out.append("float"); 147 } else if (ch == 'D') { 148 out.append("double"); 149 } else if (ch == 'S') { 150 out.append("short"); 151 } else if (ch == 'C') { 152 out.append("char"); 153 } else if (ch == 'Z') { 154 out.append("boolean"); 155 } else if (ch == 'V') { 156 out.append("void"); 157 } 158 } 159 for (int i = 0; i < len; i++){ 160 out.append("[]"); 161 } 162 } else { 163 out.append(c.getName()); 164 } 165 } 166 } 167} 168