001    package edu.rice.cs.cunit.subAnnot;
002    
003    import edu.rice.cs.cunit.classFile.ClassFileTools;
004    import edu.rice.cs.cunit.classFile.attributes.RuntimeVisibleAnnotationsAttributeInfo;
005    
006    import java.lang.reflect.*;
007    import java.util.ArrayList;
008    import java.util.List;
009    import java.io.InputStream;
010    import java.io.IOException;
011    import java.net.URL;
012    import java.security.ProtectionDomain;
013    
014    /**
015     * Extended Class class to support annotations with subclassing.
016     *
017     * @author Mathias Ricken
018     */
019    public class ClassEx<T> extends AAnnotatedElementEx {
020        /**
021         * The java.lang.Class object that represents the class.
022         */
023        public final Class<T> java;
024    
025        /**
026         * Return an extended Class instance for the class with the specified class name.
027         * @param s class name
028         * @return class
029         * @throws ClassNotFoundException if class is not found
030         */
031        @SuppressWarnings("unchecked")
032        public static ClassEx<?> forName(String s) throws ClassNotFoundException {
033            return new ClassEx(Class.forName(s));
034        }
035    
036        /**
037         * Return an extended Class instance for the class with the specified class name.
038         * @param s class name
039         * @param initialize whether the class must be initialized
040         * @param loader class loader from which the class must be loaded
041         * @return class
042         * @throws ClassNotFoundException if class is not found
043         */
044        @SuppressWarnings("unchecked")
045        public static ClassEx<?> forName(String s, boolean initialize, ClassLoader loader) throws ClassNotFoundException {
046            return new ClassEx(Class.forName(s,initialize,loader), loader);
047        }
048    
049        /**
050         * Create an extended Class instance for the specified class.
051         * @param c class
052         */
053        public ClassEx(Class<T> c) {
054            java = c;
055            if (java.isPrimitive()) {
056                _ai = null;
057                return;
058            }
059            List<RuntimeVisibleAnnotationsAttributeInfo> ais =
060                    new ArrayList<RuntimeVisibleAnnotationsAttributeInfo>();
061            Class<?> current = java;
062            while (current != null) {
063                ClassFileTools.ClassLocation cl = ClassFileTools.findClassFile(current.getName(), _classPath);
064                if (cl == null) {
065                    setClassFileNotFound(true);
066                    return;
067                }
068                final RuntimeVisibleAnnotationsAttributeInfo a = (RuntimeVisibleAnnotationsAttributeInfo)
069                        cl.getClassFile().getAttribute(RuntimeVisibleAnnotationsAttributeInfo.getAttributeName());
070                ais.add(a);
071                try {
072                    cl.close();
073                }
074                catch (IOException e) { /* ignore */ }
075                current = current.getSuperclass();
076            }
077            _ai = ais.toArray(new RuntimeVisibleAnnotationsAttributeInfo[0]);
078        }
079    
080        /**
081         * Create an extended Class instance for the specified class.
082         * @param c class
083         * @param cl class loader
084         */
085        public ClassEx(Class<T> c, ClassLoader cl) {
086            this(c);
087            _classLoader = cl;
088        }
089    
090        /**
091         * Return the annotated element.
092         *
093         * @return annotated element
094         */
095        protected AnnotatedElement getAnnotatedElement() {
096            return java;
097        }
098    
099        /**
100         * Returns a array containing extended Class objects representing all the public classes and interfaces that
101         * are members of the class represented by this extended Class object.
102         * @return array of classes
103         */
104        @SuppressWarnings("unchecked")
105        public ClassEx[] getClasses() {
106            List<ClassEx> list = new ArrayList<ClassEx>();
107            for(Class c: java.getClasses()) {
108                list.add(new ClassEx(c));
109            }
110            return list.toArray(new ClassEx[list.size()]);
111        }
112    
113        /**
114         * Returns the extended Class representing the component type of an array.
115         * If this class does not represent an array class this method returns null.
116         * @return component type
117         */
118        @SuppressWarnings("unchecked")
119        public ClassEx<?> getComponentType() {
120            Class<?> c = java.getComponentType();
121            if (c==null) { return null; }
122            return new ClassEx(c);
123        }
124    
125        /**
126         * Returns an extended Constructor object that reflects the specified public constructor of the class represented
127         * by this extended Class object. The parameterTypes parameter is an array of Class objects that identify the
128         * constructor's formal parameter types, in declared order.
129         * @param parameterTypes parameter types
130         * @return extended Constructor object
131         * @throws NoSuchMethodException if the constructor is not found
132         * @throws SecurityException if access is denied
133         */
134        public ConstructorEx<T> getConstructor(Class... parameterTypes) throws NoSuchMethodException, SecurityException {
135            Constructor<T> c = java.getConstructor(parameterTypes);
136            return new ConstructorEx<T>(c);
137        }
138    
139        /**
140         * Returns an extended Constructor object that reflects the specified public constructor of the class represented
141         * by this extended Class object. The parameterTypes parameter is an array of extended Class objects that identify
142         * the constructor's formal parameter types, in declared order.
143         * @param parameterTypes parameter types
144         * @return extended Constructor object
145         * @throws NoSuchMethodException if the constructor is not found
146         * @throws SecurityException if access is denied
147         */
148        public ConstructorEx<T> getConstructor(ClassEx... parameterTypes) throws NoSuchMethodException, SecurityException {
149            Class[] pt = new Class[parameterTypes.length];
150            for(int i=0; i<pt.length; ++i) {
151                pt[i] = parameterTypes[i].java;
152            }
153            Constructor<T> c = java.getConstructor(pt);
154            return new ConstructorEx<T>(c);
155        }
156    
157        /**
158         * Returns an array containing extended Constructor objects reflecting all the public constructors of the
159         * class represented by this extended Class object.
160         * @return array of constructors
161         * @throws SecurityException if access is denied
162         */
163        @SuppressWarnings("unchecked")
164        public ConstructorEx[] getConstructors() throws SecurityException {
165            List<ConstructorEx> list = new ArrayList<ConstructorEx>();
166            for(Constructor c: java.getConstructors()) {
167                list.add(new ConstructorEx(c));
168            }
169            return list.toArray(new ConstructorEx[list.size()]);
170        }
171    
172        /**
173         * Returns an array of extended Class objects reflecting all the classes and interfaces declared as members of
174         * the class represented by this extended Class object.
175         * @return array of classes
176         */
177        @SuppressWarnings("unchecked")
178        public ClassEx[] getDeclaredClasses() {
179            List<ClassEx> list = new ArrayList<ClassEx>();
180            for(Class c: java.getDeclaredClasses()) {
181                list.add(new ClassEx(c));
182            }
183            return list.toArray(new ClassEx[list.size()]);
184        }
185    
186        /**
187         * Returns an extended Constructor object that reflects the specified constructor of the class or interface
188         * represented by this extended Class object.
189         * @param parameterTypes parameter types
190         * @return extended Constructor object
191         * @throws NoSuchMethodException if the constructor is not found
192         * @throws SecurityException if access is denied
193         */
194        public ConstructorEx<T> getDeclaredConstructor(Class... parameterTypes)
195            throws NoSuchMethodException, SecurityException {
196            Constructor<T> c = java.getDeclaredConstructor(parameterTypes);
197            return new ConstructorEx<T>(c);
198        }
199    
200        /**
201         * Returns an extended Constructor object that reflects the specified constructor of the class or interface
202         * represented by this extended Class object.
203         * @param parameterTypes parameter types
204         * @return extended Constructor object
205         * @throws NoSuchMethodException if the constructor is not found
206         * @throws SecurityException if access is denied
207         */
208        public ConstructorEx<T> getDeclaredConstructor(ClassEx... parameterTypes) throws NoSuchMethodException, SecurityException {
209            Class[] pt = new Class[parameterTypes.length];
210            for(int i=0; i<pt.length; ++i) {
211                pt[i] = parameterTypes[i].java;
212            }
213            Constructor<T> c = java.getDeclaredConstructor(pt);
214            return new ConstructorEx<T>(c);
215        }
216    
217        /**
218         * Returns an array of extended Constructor objects reflecting all the constructors declared by the class
219         * represented by this extended Class object.
220         * @return array of constructors
221         * @throws SecurityException if access is denied
222         */
223        @SuppressWarnings("unchecked")
224        public ConstructorEx[] getDeclaredConstructors() throws SecurityException {
225            List<ConstructorEx> list = new ArrayList<ConstructorEx>();
226            for(Constructor c: java.getDeclaredConstructors()) {
227                list.add(new ConstructorEx(c));
228            }
229            return list.toArray(new ConstructorEx[list.size()]);
230        }
231    
232        /**
233         * Returns an extended Field object that reflects the specified declared field of the class or interface
234         * represented by this extended Class object.
235         * @param name field name
236         * @return extended Field object
237         * @throws NoSuchFieldException if field not found
238         * @throws SecurityException if access is denied
239         */
240        public FieldEx getDeclaredField(String name) throws NoSuchFieldException, SecurityException {
241            return new FieldEx(java.getDeclaredField(name));
242        }
243    
244        /**
245         * Returns an array of extended Field objects reflecting all the fields declared by the class
246         * represented by this extended Class object.
247         * @return array of fields
248         * @throws SecurityException if access is denied
249         */
250        public FieldEx[] getDeclaredFields() throws SecurityException {
251            List<FieldEx> list = new ArrayList<FieldEx>();
252            for(Field f: java.getDeclaredFields()) {
253                list.add(new FieldEx(f));
254            }
255            return list.toArray(new FieldEx[list.size()]);
256        }
257    
258        /**
259         * Returns an extended Method object that reflects the specified declared method of the class or interface
260         * represented by this extended Class object.
261         * @param name method name
262         * @param parameterTypes parameter types
263         * @return extended Method object
264         * @throws NoSuchMethodException if method not found
265         * @throws SecurityException if access is denied
266         */
267        public MethodEx getDeclaredMethod(String name, Class... parameterTypes)
268            throws NoSuchMethodException, SecurityException {
269            return new MethodEx(java.getDeclaredMethod(name, parameterTypes));
270        }
271    
272        /**
273         * Returns an extended Method object that reflects the specified declared method of the class or interface
274         * represented by this extended Class object.
275         * @param name method name
276         * @param parameterTypes parameter types
277         * @return extended Method object
278         * @throws NoSuchMethodException if method not found
279         * @throws SecurityException if access is denied
280         */
281        public MethodEx getDeclaredMethod(String name, ClassEx... parameterTypes)
282            throws NoSuchMethodException, SecurityException {
283            Class[] pt = new Class[parameterTypes.length];
284            for(int i=0; i<pt.length; ++i) {
285                pt[i] = parameterTypes[i].java;
286            }
287            return new MethodEx(java.getDeclaredMethod(name, pt));
288        }
289    
290        /**
291         * Returns an array of extended Method objects reflecting all the methods declared by the class
292         * represented by this extended Class object.
293         * @return array of methods
294         * @throws SecurityException if access is denied
295         */
296        public MethodEx[] getDeclaredMethods() throws SecurityException {
297            List<MethodEx> list = new ArrayList<MethodEx>();
298            for(Method m: java.getDeclaredMethods()) {
299                list.add(new MethodEx(m));
300            }
301            return list.toArray(new MethodEx[list.size()]);
302        }
303    
304        /**
305         * If the class or interface represented by this extended Class object is a member of another class, returns the
306         * extended Class object representing the class in which it was declared. This method returns null if this class
307         * or interface is not a member of any other class. If this Class object represents an array class, a primitive
308         * type, or void, then this method returns null.
309         * @return the declaring class for this class
310         */
311        @SuppressWarnings("unchecked")
312        public ClassEx<?> getDeclaringClass() {
313            Class<?> c = java.getDeclaringClass();
314            if (c==null) { return null; }
315            return new ClassEx(c);
316        }
317    
318        /**
319         * Returns the immediately enclosing class of the underlying class. If the underlying class is a top level class
320         * this method returns null.
321         * @return the enclosing class for this class
322         */
323        @SuppressWarnings("unchecked")
324        public ClassEx<?> getEnclosingClass() {
325            Class<?> c = java.getEnclosingClass();
326            if (c==null) { return null; }
327            return new ClassEx(c);
328        }
329    
330        /**
331         * If this extended Class object represents a local or anonymous class within a constructor, returns an
332         * extended Constructor object representing the immediately enclosing constructor of the underlying class.
333         * Returns null otherwise. In particular, this method returns null if the underlying class is a local or
334         * anonymous class immediately enclosed by a type declaration, instance initializer or static initializer.
335         * @return the enclosing constructor for this class
336         */
337        @SuppressWarnings("unchecked")
338        public ConstructorEx<?> getEnclosingConstructor() {
339            Constructor<?> c = java.getEnclosingConstructor();
340            if (c==null) { return null; }
341            return new ConstructorEx(c);
342        }
343    
344        /**
345         * If this extended Class object represents a local or anonymous class within a method, returns an extended Method
346         * object representing the immediately enclosing method of the underlying class. Returns null otherwise.
347         * In particular, this method returns null if the underlying class is a local or anonymous class immediately
348         * enclosed by a type declaration, instance initializer or static initializer.
349         * @return the enclosing method for this class
350         */
351        public MethodEx getEnclosingMethod() {
352            Method m = java.getEnclosingMethod();
353            if (m==null) { return null; }
354            return new MethodEx(m);
355        }
356    
357        /**
358         * Returns an extended Field object that reflects the specified field of the class or interface
359         * represented by this extended Class object.
360         * @param name field name
361         * @return extended Field object
362         * @throws NoSuchFieldException if field not found
363         * @throws SecurityException if access is denied
364         */
365        public FieldEx getField(String name) throws NoSuchFieldException, SecurityException {
366            return new FieldEx(java.getField(name));
367        }
368    
369        /**
370         * Returns an array containing extended Field objects reflecting all the accessible public fields of the
371         * class or interface represented by this extended Class object.
372         * @return array of fields
373         * @throws SecurityException if access is denied
374         */
375        public FieldEx[] getFields() throws SecurityException {
376            List<FieldEx> list = new ArrayList<FieldEx>();
377            for(Field f: java.getFields()) {
378                list.add(new FieldEx(f));
379            }
380            return list.toArray(new FieldEx[list.size()]);
381        }
382    
383        /**
384         * Returns an extended Method object that reflects the specified method of the class or interface
385         * represented by this extended Class object.
386         * @param name method name
387         * @param parameterTypes parameter types
388         * @return extended Method object
389         * @throws NoSuchMethodException if method not found
390         * @throws SecurityException if access is denied
391         */
392        public MethodEx getMethod(String name, Class... parameterTypes)
393            throws NoSuchMethodException, SecurityException {
394            return new MethodEx(java.getMethod(name, parameterTypes));
395        }
396    
397        /**
398         * Returns an array containing extended Method objects reflecting all the public member methods of the class
399         * or interface represented by this extended Class object, including those declared by the class or interface
400         * and those inherited from superclasses and superinterfaces.
401         * @param name method name
402         * @param parameterTypes parameter types
403         * @return extended Method object
404         * @throws NoSuchMethodException if method not found
405         * @throws SecurityException if access is denied
406         */
407        public MethodEx getMethod(String name, ClassEx... parameterTypes)
408            throws NoSuchMethodException, SecurityException {
409            Class[] pt = new Class[parameterTypes.length];
410            for(int i=0; i<pt.length; ++i) {
411                pt[i] = parameterTypes[i].java;
412            }
413            return new MethodEx(java.getMethod(name, pt));
414        }
415    
416        /**
417         * Returns an array containing extended Method objects reflecting all the public member methods of the class
418         * or interface represented by this extended Class object, including those declared by the class or interface
419         * and those inherited from superclasses and superinterfaces.
420         * @return array of methods
421         * @throws SecurityException if access is denied
422         */
423        public MethodEx[] getMethods() throws SecurityException {
424            List<MethodEx> list = new ArrayList<MethodEx>();
425            for(Method m: java.getMethods()) {
426                list.add(new MethodEx(m));
427            }
428            return list.toArray(new MethodEx[list.size()]);
429        }
430    
431        /**
432         * Determines the interfaces implemented by the class or interface represented by this object.
433         * @return array of interfaces
434         */
435        @SuppressWarnings("unchecked")
436        public ClassEx[] getInterfaces() {
437            List<ClassEx> list = new ArrayList<ClassEx>();
438            for(Class c: java.getInterfaces()) {
439                list.add(new ClassEx(c));
440            }
441            return list.toArray(new ClassEx[list.size()]);
442        }
443    
444        /**
445         * Gets the package for this class.
446         * @return package
447         */
448        public PackageEx getPackage() {
449            Package p = java.getPackage();
450            if (p==null) { return null; }
451            return new PackageEx(p);
452        }
453    
454        /**
455         * Returns the extended Class representing the superclass of the entity (class, interface, primitive type or void)
456         * represented by this extended Class.
457         * @return superclass
458         */
459        @SuppressWarnings("unchecked")
460        public ClassEx<? super T> getSuperclass() {
461            Class<? super T> c = java.getSuperclass();
462            if (c==null) { return null; }
463            return new ClassEx(c);
464        }
465    
466        /**
467         * Converts the object to a string. The string representation is the string "class" or "interface", followed by a
468         * space, and then by the fully qualified name of the class in the format returned by <code>getName</code>.  If this
469         * <code>Class</code> object represents a primitive type, this method returns the name of the primitive type.  If
470         * this <code>Class</code> object represents void this method returns "void".
471         *
472         * @return a string representation of this class object.
473         */
474        public String toString() {
475            return java.toString();
476        }
477    
478        /**
479         * Creates a new instance of the class represented by this <tt>Class</tt> object.  The class is instantiated as if
480         * by a <code>new</code> expression with an empty argument list.  The class is initialized if it has not already
481         * been initialized.
482         * <p/>
483         * <p>Note that this method propagates any exception thrown by the nullary constructor, including a checked
484         * exception. Use of this method effectively bypasses the compile-time exception checking that would otherwise be
485         * performed by the compiler. The {@link java.lang.reflect.Constructor#newInstance(Object...)
486         * Constructor.newInstance} method avoids this problem by wrapping any exception thrown by the constructor in a
487         * (checked) {@link java.lang.reflect.InvocationTargetException}.
488         *
489         * @return a newly allocated instance of the class represented by this object.
490         *
491         * @throws IllegalAccessException      if the class or its nullary constructor is not accessible.
492         * @throws InstantiationException      if this <code>Class</code> represents an abstract class, an interface, an
493         *                                     array class, a primitive type, or void; or if the class has no nullary
494         *                                     constructor; or if the instantiation fails for some other reason.
495         * @throws ExceptionInInitializerError if the initialization provoked by this method fails.
496         * @throws SecurityException           If a security manager, <i>s</i>, is present and any of the following
497         *                                     conditions is met:
498         *                                     <p/>
499         *                                     <ul>
500         *                                     <p/>
501         *                                     <li> invocation of <tt>{@link SecurityManager#checkMemberAccess
502         *                                     s.checkMemberAccess(this, Member.PUBLIC)}</tt> denies creation of new
503         *                                     instances of this class
504         *                                     <p/>
505         *                                     <li> the caller's class loader is not the same as or an ancestor of the class
506         *                                     loader for the current class and invocation of <tt>{@link
507         *                                     SecurityManager#checkPackageAccess s.checkPackageAccess()}</tt> denies access
508         *                                     to the package of this class
509         *                                     <p/>
510         *                                     </ul>
511         */
512        public T newInstance() throws InstantiationException, IllegalAccessException {
513            return java.newInstance();
514        }
515    
516        /**
517         * Determines if the specified <code>Object</code> is assignment-compatible with the object represented by this
518         * <code>Class</code>.  This method is the dynamic equivalent of the Java language <code>instanceof</code> operator.
519         * The method returns <code>true</code> if the specified <code>Object</code> argument is non-null and can be cast to
520         * the reference type represented by this <code>Class</code> object without raising a <code>ClassCastException.</code>
521         * It returns <code>false</code> otherwise.
522         * <p/>
523         * <p> Specifically, if this <code>Class</code> object represents a declared class, this method returns
524         * <code>true</code> if the specified <code>Object</code> argument is an instance of the represented class (or of any
525         * of its subclasses); it returns <code>false</code> otherwise. If this <code>Class</code> object represents an array
526         * class, this method returns <code>true</code> if the specified <code>Object</code> argument can be converted to an
527         * object of the array class by an identity conversion or by a widening reference conversion; it returns
528         * <code>false</code> otherwise. If this <code>Class</code> object represents an interface, this method returns
529         * <code>true</code> if the class or any superclass of the specified <code>Object</code> argument implements this
530         * interface; it returns <code>false</code> otherwise. If this <code>Class</code> object represents a primitive type,
531         * this method returns <code>false</code>.
532         *
533         * @param obj the object to check
534         *
535         * @return true if <code>obj</code> is an instance of this class
536         *
537         * @since JDK1.1
538         */
539        public boolean isInstance(Object obj) {
540            return java.isInstance(obj);
541        }
542    
543        /**
544         * Determines if the class or interface represented by this <code>Class</code> object is either the same as, or is a
545         * superclass or superinterface of, the class or interface represented by the specified <code>Class</code> parameter.
546         * It returns <code>true</code> if so; otherwise it returns <code>false</code>. If this <code>Class</code> object
547         * represents a primitive type, this method returns <code>true</code> if the specified <code>Class</code> parameter is
548         * exactly this <code>Class</code> object; otherwise it returns <code>false</code>.
549         * <p/>
550         * <p> Specifically, this method tests whether the type represented by the specified <code>Class</code> parameter can
551         * be converted to the type represented by this <code>Class</code> object via an identity conversion or via a widening
552         * reference conversion. See <em>The Java Language Specification</em>, sections 5.1.1 and 5.1.4 , for details.
553         *
554         * @param cls the <code>Class</code> object to be checked
555         *
556         * @return the <code>boolean</code> value indicating whether objects of the type <code>cls</code> can be assigned to
557         *         objects of this class
558         *
559         * @throws NullPointerException if the specified Class parameter is null.
560         * @since JDK1.1
561         */
562        public boolean isAssignableFrom(java.lang.Class cls) {
563            return java.isAssignableFrom(cls);
564        }
565    
566        /**
567         * Determines if the specified <code>Class</code> object represents an interface type.
568         *
569         * @return <code>true</code> if this object represents an interface; <code>false</code> otherwise.
570         */
571        public boolean isInterface() {
572            return java.isInterface();
573        }
574    
575        /**
576         * Determines if this <code>Class</code> object represents an array class.
577         *
578         * @return <code>true</code> if this object represents an array class; <code>false</code> otherwise.
579         *
580         * @since JDK1.1
581         */
582        public boolean isArray() {
583            return java.isArray();
584        }
585    
586        /**
587         * Determines if the specified <code>Class</code> object represents a primitive type.
588         * <p/>
589         * <p> There are nine predefined <code>Class</code> objects to represent the eight primitive types and void.  These
590         * are created by the Java Virtual Machine, and have the same names as the primitive types that they represent,
591         * namely <code>boolean</code>, <code>byte</code>, <code>char</code>, <code>short</code>, <code>int</code>,
592         * <code>long</code>, <code>float</code>, and <code>double</code>.
593         * <p/>
594         * <p> These objects may only be accessed via the following public static final variables, and are the only
595         * <code>Class</code> objects for which this method returns <code>true</code>.
596         *
597         * @return true if and only if this class represents a primitive type
598         *
599         * @see Boolean#TYPE
600         * @see Character#TYPE
601         * @see Byte#TYPE
602         * @see Short#TYPE
603         * @see Integer#TYPE
604         * @see Long#TYPE
605         * @see Float#TYPE
606         * @see Double#TYPE
607         * @see Void#TYPE
608         * @since JDK1.1
609         */
610        public boolean isPrimitive() {
611            return java.isPrimitive();
612        }
613    
614        /**
615         * Returns true if this <tt>Class</tt> object represents an annotation type.  Note that if this method returns true,
616         * {@link #isInterface()} would also return true, as all annotation types are also interfaces.
617         *
618         * @return <tt>true</tt> if this class object represents an annotation type; <tt>false</tt> otherwise
619         *
620         * @since 1.5
621         */
622        public boolean isAnnotation() {
623            return java.isAnnotation();
624        }
625    
626        /**
627         * Returns <tt>true</tt> if this class is a synthetic class; returns <tt>false</tt> otherwise.
628         *
629         * @return <tt>true</tt> if and only if this class is a synthetic class as defined by the Java Language
630         *         Specification.
631         *
632         * @since 1.5
633         */
634        public boolean isSynthetic() {
635            return java.isSynthetic();
636        }
637    
638        /**
639         * Returns the  name of the entity (class, interface, array class, primitive type, or void) represented by this
640         * <tt>Class</tt> object, as a <tt>String</tt>.
641         * <p/>
642         * <p> If this class object represents a reference type that is not an array type then the binary name of the class
643         * is returned, as specified by the Java Language Specification, Second Edition.
644         * <p/>
645         * <p> If this class object represents a primitive type or void, then the name returned is a <tt>String</tt> equal
646         * to the Java language keyword corresponding to the primitive type or void.
647         * <p/>
648         * <p> If this class object represents a class of arrays, then the internal form of the name consists of the name of
649         * the element type preceded by one or more '<tt>[</tt>' characters representing the depth of the array nesting.
650         * The encoding of element type names is as follows:
651         * <p/>
652         * <blockquote><table summary="Element types and encodings"> <tr><th> Element Type <th> Encoding <tr><td> boolean
653         * <td align=center> Z <tr><td> byte         <td align=center> B <tr><td> char         <td align=center> C <tr><td>
654         * class or interface  <td align=center> L<i>classname;</i> <tr><td> double       <td align=center> D <tr><td> float
655         * <td align=center> F <tr><td> int          <td align=center> I <tr><td> long         <td align=center> J <tr><td>
656         * short        <td align=center> S </table></blockquote>
657         * <p/>
658         * <p> The class or interface name <i>classname</i> is the binary name of the class specified above.
659         * <p/>
660         * <p> Examples:
661         * <blockquote><pre>
662         * String.class.getName()
663         *     returns "java.lang.String"
664         * byte.class.getName()
665         *     returns "byte"
666         * (new Object[3]).getClass().getName()
667         *     returns "[Ljava.lang.Object;"
668         * (new int[3][4][5][6][7][8][9]).getClass().getName()
669         *     returns "[[[[[[[I"
670         * </pre></blockquote>
671         *
672         * @return the name of the class or interface represented by this object.
673         */
674        public String getName() {
675            return java.getName();
676        }
677    
678        /**
679         * Returns the class loader for the class.  Some implementations may use null to represent the bootstrap class
680         * loader. This method will return null in such implementations if this class was loaded by the bootstrap class
681         * loader.
682         * <p/>
683         * <p> If a security manager is present, and the caller's class loader is not null and the caller's class loader is
684         * not the same as or an ancestor of the class loader for the class whose class loader is requested, then this
685         * method calls the security manager's <code>checkPermission</code> method with a
686         * <code>RuntimePermission("getClassLoader")</code> permission to ensure it's ok to access the class loader for the
687         * class.
688         * <p/>
689         * <p>If this object represents a primitive type or void, null is returned.
690         *
691         * @return the class loader that loaded the class or interface represented by this object.
692         *
693         * @throws SecurityException if a security manager exists and its <code>checkPermission</code> method denies access
694         *                           to the class loader for the class.
695         * @see ClassLoader
696         * @see SecurityManager#checkPermission
697         * @see RuntimePermission
698         */
699        public ClassLoader getClassLoader() {
700            return java.getClassLoader();
701        }
702    
703        /**
704         * Returns an array of <tt>TypeVariable</tt> objects that represent the type variables declared by the generic
705         * declaration represented by this <tt>GenericDeclaration</tt> object, in declaration order.  Returns an array of
706         * length 0 if the underlying generic declaration declares no type variables.
707         *
708         * @return an array of <tt>TypeVariable</tt> objects that represent the type variables declared by this generic
709         *         declaration
710         *
711         * @throws GenericSignatureFormatError if the generic signature of this generic declaration does not conform to the
712         *                                     format specified in the Java Virtual Machine Specification, 3rd edition
713         * @since 1.5
714         */
715        public TypeVariable[] getTypeParameters() {
716            return java.getTypeParameters();
717        }
718    
719        /**
720         * Returns the <tt>Type</tt> representing the direct superclass of the entity (class, interface, primitive type or
721         * void) represented by this <tt>Class</tt>.
722         * <p/>
723         * <p>If the superclass is a parameterized type, the <tt>Type</tt> object returned must accurately reflect the actual
724         * type parameters used in the source code. The parameterized type representing the superclass is created if it had not
725         * been created before. See the declaration of {@link java.lang.reflect.ParameterizedType ParameterizedType} for the
726         * semantics of the creation process for parameterized types.  If this <tt>Class</tt> represents either the
727         * <tt>Object</tt> class, an interface, a primitive type, or void, then null is returned.  If this object represents an
728         * array class then the <tt>Class</tt> object representing the <tt>Object</tt> class is returned.
729         *
730         * @return the superclass of the class represented by this object
731         *
732         * @throws GenericSignatureFormatError if the generic class signature does not conform to the format specified in the
733         *                                     Java Virtual Machine Specification, 3rd edition
734         * @throws TypeNotPresentException     if the generic superclass refers to a non-existent type declaration
735         * @throws MalformedParameterizedTypeException
736         *                                     if the generic superclass refers to a parameterized type that cannot be
737         *                                     instantiated  for any reason
738         * @since 1.5
739         */
740        public Type getGenericSuperclass() {
741            return java.getGenericSuperclass();
742        }
743    
744        /**
745         * Returns the <tt>Type</tt>s representing the interfaces directly implemented by the class or interface represented by
746         * this object.
747         * <p/>
748         * <p>If a superinterface is a parameterized type, the <tt>Type</tt> object returned for it must accurately reflect the
749         * actual type parameters used in the source code. The parameterized type representing each superinterface is created
750         * if it had not been created before. See the declaration of {@link java.lang.reflect.ParameterizedType
751         * ParameterizedType} for the semantics of the creation process for parameterized types.
752         * <p/>
753         * <p> If this object represents a class, the return value is an array containing objects representing all interfaces
754         * implemented by the class. The order of the interface objects in the array corresponds to the order of the interface
755         * names in the <tt>implements</tt> clause of the declaration of the class represented by this object.  In the case of
756         * an array class, the interfaces <tt>Cloneable</tt> and <tt>Serializable</tt> are returned in that order.
757         * <p/>
758         * <p>If this object represents an interface, the array contains objects representing all interfaces directly extended
759         * by the interface.  The order of the interface objects in the array corresponds to the order of the interface names
760         * in the <tt>extends</tt> clause of the declaration of the interface represented by this object.
761         * <p/>
762         * <p>If this object represents a class or interface that implements no interfaces, the method returns an array of
763         * length 0.
764         * <p/>
765         * <p>If this object represents a primitive type or void, the method returns an array of length 0.
766         *
767         * @return an array of interfaces implemented by this class
768         *
769         * @throws GenericSignatureFormatError if the generic class signature does not conform to the format specified in the
770         *                                     Java Virtual Machine Specification, 3rd edition
771         * @throws TypeNotPresentException     if any of the generic superinterfaces refers to a non-existent type declaration
772         * @throws MalformedParameterizedTypeException
773         *                                     if any of the generic superinterfaces refer to a parameterized type that cannot
774         *                                     be instantiated  for any reason
775         * @since 1.5
776         */
777        public Type[] getGenericInterfaces() {
778            return java.getGenericInterfaces();
779        }
780    
781        /**
782         * Returns the Java language modifiers for this class or interface, encoded in an integer. The modifiers consist of
783         * the Java Virtual Machine's constants for <code>public</code>, <code>protected</code>, <code>private</code>,
784         * <code>final</code>, <code>static</code>, <code>abstract</code> and <code>interface</code>; they should be decoded
785         * using the methods of class <code>Modifier</code>.
786         * <p/>
787         * <p> If the underlying class is an array class, then its <code>public</code>, <code>private</code> and
788         * <code>protected</code> modifiers are the same as those of its component type.  If this <code>Class</code>
789         * represents a primitive type or void, its <code>public</code> modifier is always <code>true</code>, and its
790         * <code>protected</code> and <code>private</code> modifiers are always <code>false</code>. If this object
791         * represents an array class, a primitive type or void, then its <code>final</code> modifier is always
792         * <code>true</code> and its interface modifier is always <code>false</code>. The values of its other modifiers are
793         * not determined by this specification.
794         * <p/>
795         * <p> The modifier encodings are defined in <em>The Java Virtual Machine Specification</em>, table 4.1.
796         *
797         * @return the <code>int</code> representing the modifiers for this class
798         *
799         * @see java.lang.reflect.Modifier
800         * @since JDK1.1
801         */
802        public int getModifiers() {
803            return java.getModifiers();
804        }
805    
806        /**
807         * Gets the signers of this class.
808         *
809         * @return the signers of this class, or null if there are no signers.  In particular, this method returns null if
810         *         this object represents a primitive type or void.
811         *
812         * @since JDK1.1
813         */
814        public Object[] getSigners() {
815            return java.getSigners();
816        }
817    
818        /**
819         * Returns the simple name of the underlying class as given in the source code. Returns an empty string if the
820         * underlying class is anonymous.
821         * <p/>
822         * <p>The simple name of an array is the simple name of the component type with "[]" appended.  In particular the
823         * simple name of an array whose component type is anonymous is "[]".
824         *
825         * @return the simple name of the underlying class
826         *
827         * @since 1.5
828         */
829        public String getSimpleName() {
830            return java.getSimpleName();
831        }
832    
833        /**
834         * Returns the canonical name of the the underlying class as defined by the Java Language Specification.  Returns
835         * null if the underlying class does not have a canonical name (i.e., if it is a local or anonymous class or an
836         * array whose component type does not have a canonical name).
837         *
838         * @return the canonical name of the underlying class if it exists, and <tt>null</tt> otherwise.
839         *
840         * @since 1.5
841         */
842        public String getCanonicalName() {
843            return java.getCanonicalName();
844        }
845    
846        /**
847         * Returns <tt>true</tt> if and only if the underlying class is an anonymous class.
848         *
849         * @return <tt>true</tt> if and only if this class is an anonymous class.
850         *
851         * @since 1.5
852         */
853        public boolean isAnonymousClass() {
854            return java.isAnonymousClass();
855        }
856    
857        /**
858         * Returns <tt>true</tt> if and only if the underlying class is a local class.
859         *
860         * @return <tt>true</tt> if and only if this class is a local class.
861         *
862         * @since 1.5
863         */
864        public boolean isLocalClass() {
865            return java.isLocalClass();
866        }
867    
868        /**
869         * Returns <tt>true</tt> if and only if the underlying class is a member class.
870         *
871         * @return <tt>true</tt> if and only if this class is a member class.
872         *
873         * @since 1.5
874         */
875        public boolean isMemberClass() {
876            return java.isMemberClass();
877        }
878    
879        /**
880         * Finds a resource with a given name.  The rules for searching resources associated with a given class are implemented
881         * by the defining {@linkplain ClassLoader class loader} of the class.  This method delegates to this object's class
882         * loader.  If this object was loaded by the bootstrap class loader, the method delegates to {@link
883         * ClassLoader#getSystemResourceAsStream}.
884         * <p/>
885         * <p> Before delegation, an absolute resource name is constructed from the given resource name using this algorithm:
886         * <p/>
887         * <ul>
888         * <p/>
889         * <li> If the <tt>name</tt> begins with a <tt>'/'</tt> (<tt>'&#92;u002f'</tt>), then the absolute name of the resource
890         * is the portion of the <tt>name</tt> following the <tt>'/'</tt>.
891         * <p/>
892         * <li> Otherwise, the absolute name is of the following form:
893         * <p/>
894         * <blockquote><pre>
895         *   <tt>modified_package_name</tt>/<tt>name</tt>
896         * </pre></blockquote>
897         * <p/>
898         * <p> Where the <tt>modified_package_name</tt> is the package name of this object with <tt>'/'</tt> substituted for
899         * <tt>'.'</tt> (<tt>'&#92;u002e'</tt>).
900         * <p/>
901         * </ul>
902         *
903         * @param name name of the desired resource
904         *
905         * @return A {@link java.io.InputStream} object or <tt>null</tt> if no resource with this name is found
906         *
907         * @throws NullPointerException If <tt>name</tt> is <tt>null</tt>
908         * @since JDK1.1
909         */
910        public InputStream getResourceAsStream(String name) {
911            return java.getResourceAsStream(name);
912        }
913    
914        /**
915         * Finds a resource with a given name.  The rules for searching resources associated with a given class are implemented
916         * by the defining {@linkplain ClassLoader class loader} of the class.  This method delegates to this object's class
917         * loader.  If this object was loaded by the bootstrap class loader, the method delegates to {@link
918         * ClassLoader#getSystemResource}.
919         * <p/>
920         * <p> Before delegation, an absolute resource name is constructed from the given resource name using this algorithm:
921         * <p/>
922         * <ul>
923         * <p/>
924         * <li> If the <tt>name</tt> begins with a <tt>'/'</tt> (<tt>'&#92;u002f'</tt>), then the absolute name of the resource
925         * is the portion of the <tt>name</tt> following the <tt>'/'</tt>.
926         * <p/>
927         * <li> Otherwise, the absolute name is of the following form:
928         * <p/>
929         * <blockquote><pre>
930         *   <tt>modified_package_name</tt>/<tt>name</tt>
931         * </pre></blockquote>
932         * <p/>
933         * <p> Where the <tt>modified_package_name</tt> is the package name of this object with <tt>'/'</tt> substituted for
934         * <tt>'.'</tt> (<tt>'&#92;u002e'</tt>).
935         * <p/>
936         * </ul>
937         *
938         * @param name name of the desired resource
939         *
940         * @return A  {@link java.net.URL} object or <tt>null</tt> if no resource with this name is found
941         *
942         * @since JDK1.1
943         */
944        public URL getResource(String name) {
945            return java.getResource(name);
946        }
947    
948        /**
949         * Returns the <code>ProtectionDomain</code> of this class.  If there is a security manager installed, this method
950         * first calls the security manager's <code>checkPermission</code> method with a <code>RuntimePermission("getProtectionDomain")</code>
951         * permission to ensure it's ok to get the <code>ProtectionDomain</code>.
952         *
953         * @return the ProtectionDomain of this class
954         *
955         * @throws SecurityException if a security manager exists and its <code>checkPermission</code> method doesn't allow
956         *                           getting the ProtectionDomain.
957         * @see java.security.ProtectionDomain
958         * @see SecurityManager#checkPermission
959         * @see RuntimePermission
960         * @since 1.2
961         */
962        public ProtectionDomain getProtectionDomain() {
963            return java.getProtectionDomain();
964        }
965    
966        /**
967         * Returns the assertion status that would be assigned to this class if it were to be initialized at the time this
968         * method is invoked. If this class has had its assertion status set, the most recent setting will be returned;
969         * otherwise, if any package default assertion status pertains to this class, the most recent setting for the most
970         * specific pertinent package default assertion status is returned; otherwise, if this class is not a system class
971         * (i.e., it has a class loader) its class loader's default assertion status is returned; otherwise, the system
972         * class default assertion status is returned.
973         * <p/>
974         * Few programmers will have any need for this method; it is provided for the benefit of the JRE itself.  (It allows
975         * a class to determine at the time that it is initialized whether assertions should be enabled.) Note that this
976         * method is not guaranteed to return the actual assertion status that was (or will be) associated with the
977         * specified class when it was (or will be) initialized.
978         *
979         * @return the desired assertion status of the specified class.
980         *
981         * @see ClassLoader#setClassAssertionStatus
982         * @see ClassLoader#setPackageAssertionStatus
983         * @see ClassLoader#setDefaultAssertionStatus
984         * @since 1.4
985         */
986        public boolean desiredAssertionStatus() {
987            return java.desiredAssertionStatus();
988        }
989    
990        /**
991         * Returns true if and only if this class was declared as an enum in the source code.
992         *
993         * @return true if and only if this class was declared as an enum in the source code
994         *
995         * @since 1.5
996         */
997        public boolean isEnum() {
998            return java.isEnum();
999        }
1000    
1001        /**
1002         * Returns the elements of this enum class or null if this Class object does not represent an enum type.
1003         *
1004         * @return an array containing the values comprising the enum class represented by this Class object in the order
1005         *         they're declared, or null if this Class object does not represent an enum type
1006         *
1007         * @since 1.5
1008         */
1009        public Object[] getEnumConstants() {
1010            return java.getEnumConstants();
1011        }
1012    
1013        /**
1014         * Casts an object to the class or interface represented by this <tt>Class</tt> object.
1015         *
1016         * @param obj the object to be cast
1017         *
1018         * @return the object after casting, or null if obj is null
1019         *
1020         * @throws ClassCastException if the object is not null and is not assignable to the type T.
1021         * @since 1.5
1022         */
1023        public Object cast(Object obj) {
1024            return java.cast(obj);
1025        }
1026    
1027        /**
1028         * Casts this <tt>Class</tt> object to represent a subclass of the class represented by the specified class object.
1029         * Checks that that the cast is valid, and throws a <tt>ClassCastException</tt> if it is not.  If this method succeeds,
1030         * it always returns a reference to this class object.
1031         * <p/>
1032         * <p>This method is useful when a client needs to "narrow" the type of a <tt>Class</tt> object to pass it to an API
1033         * that restricts the <tt>Class</tt> objects that it is willing to accept.  A cast would generate a compile-time
1034         * warning, as the correctness of the cast could not be checked at runtime (because generic types are implemented by
1035         * erasure).
1036         * @param clazz superclass
1037         * @return this <tt>Class</tt> object, cast to represent a subclass of the specified class object.
1038         *
1039         * @throws ClassCastException if this <tt>Class</tt> object does not represent a subclass of the specified class (here
1040         *                            "subclass" includes the class itself).
1041         * @since 1.5
1042         */
1043        @SuppressWarnings("unchecked")
1044        public <U> ClassEx<? extends U> asSubclass(ClassEx<U> clazz) {
1045            return new ClassEx(java.asSubclass(clazz.java));
1046        }
1047    
1048        /**
1049         * Compares this <code>Constructor</code> against the specified object. Returns true if the objects are the same.  Two
1050         * <code>Constructor</code> objects are the same if they were declared by the same class and have the same formal
1051         * parameter types.
1052         */
1053        public boolean equals(Object obj) {
1054            return (obj!=null)&&(obj.getClass().equals(this.getClass()) && (java.equals(obj)));
1055        }
1056    
1057        /**
1058         * Returns a hashcode for this <code>Constructor</code>. The hashcode is the same as the hashcode for the underlying
1059         * constructor's declaring class name.
1060         */
1061        public int hashCode() {
1062            return java.hashCode();
1063        }
1064    }