183 * this {@code Class} object represents void this method returns
184 * "void". If this {@code Class} object represents an array type,
185 * this method returns "class " followed by {@code getName}.
186 *
187 * @return a string representation of this class object.
188 */
189 public String toString() {
190 return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
191 + getName();
192 }
193
194 /**
195 * Returns a string describing this {@code Class}, including
196 * information about modifiers and type parameters.
197 *
198 * The string is formatted as a list of type modifiers, if any,
199 * followed by the kind of type (empty string for primitive types
200 * and {@code class}, {@code enum}, {@code interface}, or
201 * <code>@</code>{@code interface}, as appropriate), followed
202 * by the type's name, followed by an angle-bracketed
203 * comma-separated list of the type's type parameters, if any.
204 *
205 * A space is used to separate modifiers from one another and to
206 * separate any modifiers from the kind of type. The modifiers
207 * occur in canonical order. If there are no type parameters, the
208 * type parameter list is elided.
209 *
210 * For an array type, the string starts with the type name,
211 * followed by an angle-bracketed comma-separated list of the
212 * type's type parameters, if any, followed by a sequence of
213 * {@code []} characters, one set of brackets per dimension of
214 * the array.
215 *
216 * <p>Note that since information about the runtime representation
217 * of a type is being generated, modifiers not present on the
218 * originating source code or illegal on the originating source
219 * code may be present.
220 *
221 * @return a string describing this {@code Class}, including
222 * information about modifiers and type parameters
223 *
247
248 if (isAnnotation()) {
249 sb.append('@');
250 }
251 if (isInterface()) { // Note: all annotation types are interfaces
252 sb.append("interface");
253 } else {
254 if (isEnum())
255 sb.append("enum");
256 else
257 sb.append("class");
258 }
259 sb.append(' ');
260 sb.append(getName());
261 }
262
263 TypeVariable<?>[] typeparms = component.getTypeParameters();
264 if (typeparms.length > 0) {
265 StringJoiner sj = new StringJoiner(",", "<", ">");
266 for(TypeVariable<?> typeparm: typeparms) {
267 sj.add(typeparm.getTypeName());
268 }
269 sb.append(sj.toString());
270 }
271
272 for (int i = 0; i < arrayDepth; i++)
273 sb.append("[]");
274
275 return sb.toString();
276 }
277 }
278
279 /**
280 * Returns the {@code Class} object associated with the class or
281 * interface with the given string name. Invoking this method is
282 * equivalent to:
283 *
284 * <blockquote>
285 * {@code Class.forName(className, true, currentLoader)}
286 * </blockquote>
287 *
288 * where {@code currentLoader} denotes the defining class loader of
289 * the current class.
290 *
291 * <p> For example, the following code fragment returns the
292 * runtime {@code Class} descriptor for the class named
293 * {@code java.lang.Thread}:
294 *
295 * <blockquote>
296 * {@code Class t = Class.forName("java.lang.Thread")}
|
183 * this {@code Class} object represents void this method returns
184 * "void". If this {@code Class} object represents an array type,
185 * this method returns "class " followed by {@code getName}.
186 *
187 * @return a string representation of this class object.
188 */
189 public String toString() {
190 return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
191 + getName();
192 }
193
194 /**
195 * Returns a string describing this {@code Class}, including
196 * information about modifiers and type parameters.
197 *
198 * The string is formatted as a list of type modifiers, if any,
199 * followed by the kind of type (empty string for primitive types
200 * and {@code class}, {@code enum}, {@code interface}, or
201 * <code>@</code>{@code interface}, as appropriate), followed
202 * by the type's name, followed by an angle-bracketed
203 * comma-separated list of the type's type parameters, if any,
204 * including informative bounds on the type parameters, if any.
205 *
206 * A space is used to separate modifiers from one another and to
207 * separate any modifiers from the kind of type. The modifiers
208 * occur in canonical order. If there are no type parameters, the
209 * type parameter list is elided.
210 *
211 * For an array type, the string starts with the type name,
212 * followed by an angle-bracketed comma-separated list of the
213 * type's type parameters, if any, followed by a sequence of
214 * {@code []} characters, one set of brackets per dimension of
215 * the array.
216 *
217 * <p>Note that since information about the runtime representation
218 * of a type is being generated, modifiers not present on the
219 * originating source code or illegal on the originating source
220 * code may be present.
221 *
222 * @return a string describing this {@code Class}, including
223 * information about modifiers and type parameters
224 *
248
249 if (isAnnotation()) {
250 sb.append('@');
251 }
252 if (isInterface()) { // Note: all annotation types are interfaces
253 sb.append("interface");
254 } else {
255 if (isEnum())
256 sb.append("enum");
257 else
258 sb.append("class");
259 }
260 sb.append(' ');
261 sb.append(getName());
262 }
263
264 TypeVariable<?>[] typeparms = component.getTypeParameters();
265 if (typeparms.length > 0) {
266 StringJoiner sj = new StringJoiner(",", "<", ">");
267 for(TypeVariable<?> typeparm: typeparms) {
268 sj.add(typeVarBounds(typeparm));
269 }
270 sb.append(sj.toString());
271 }
272
273 for (int i = 0; i < arrayDepth; i++)
274 sb.append("[]");
275
276 return sb.toString();
277 }
278 }
279
280 String typeVarBounds(TypeVariable<?> typeVar) {
281 Type[] bounds = typeVar.getBounds();
282 if (bounds.length == 1 && bounds[0].equals(Object.class)) {
283 return typeVar.getName();
284 } else {
285 StringJoiner sj = new StringJoiner(" & ");
286 for (Type bound : bounds) {
287 sj.add(bound.getTypeName());
288 }
289 return typeVar.getName() + " extends " + sj.toString();
290 }
291 }
292
293 /**
294 * Returns the {@code Class} object associated with the class or
295 * interface with the given string name. Invoking this method is
296 * equivalent to:
297 *
298 * <blockquote>
299 * {@code Class.forName(className, true, currentLoader)}
300 * </blockquote>
301 *
302 * where {@code currentLoader} denotes the defining class loader of
303 * the current class.
304 *
305 * <p> For example, the following code fragment returns the
306 * runtime {@code Class} descriptor for the class named
307 * {@code java.lang.Thread}:
308 *
309 * <blockquote>
310 * {@code Class t = Class.forName("java.lang.Thread")}
|