package java.lang;

import java.io.InputStream;
import ej.annotation.Nullable;

/**
 * Instances of the class {@code Class} represent classes and interfaces in a running Java
 * application. An enum is a kind of class and an annotation is a kind of interface. Every array
 * also belongs to a class that is reflected as a {@code Class} object that is shared by all arrays
 * with the same element type and number of dimensions. The primitive Java types ({@code boolean},
 * {@code byte}, {@code char}, {@code short}, {@code int}, {@code long}, {@code float}, and
 * {@code double}), and the keyword {@code void} are also represented as {@code Class} objects.
 *
 * <p>
 * {@code Class} has no public constructor. Instead {@code Class} objects are constructed
 * automatically by the Java Virtual Machine as classes are loaded.
 *
 * <p>
 * The following example uses a {@code Class} object to print the class name of an object:
 *
 * <blockquote>
 *
 * <pre>
 * void printClassName(Object obj) {
 * 	System.out.println(&quot;The class of &quot; + obj + &quot; is &quot; + obj.getClass().getName());
 * }
 * </pre>
 *
 * </blockquote>
 *
 * <p>
 * It is also possible to get the {@code Class} object for a named type (or for void) using a class
 * literal. See Section 15.8.2 of <cite>The Java&trade; Language Specification</cite>. For example:
 *
 * <blockquote> {@code System.out.println("The name of class Foo is: "+Foo.class.getName());}
 * </blockquote>
 *
 * @param <T>
 *        the type of the class modeled by this {@code Class} object. For example, the type of
 *        {@code String.class} is {@code Class<String>}. Use {@code Class<?>} if the class being
 *        modeled is unknown.
 */
public final class Class<T> implements java.lang.reflect.AnnotatedElement, java.lang.reflect.GenericDeclaration, java.io.Serializable, java.lang.reflect.Type {

    /**
     * Returns the {@code Class} object associated with the class or interface with the given string
     * name.
     *
     * <p>
     * For example, the following code fragment returns the runtime {@code Class} descriptor for the
     * class named {@code java.lang.Thread}:
     *
     * <blockquote> {@code Class t = Class.forName("java.lang.Thread")} </blockquote>
     * <p>
     * A call to {@code forName("X")} causes the class named {@code X} to be initialized.
     *
     * @param className
     *        the fully qualified name of the desired class.
     * @return the {@code Class} object for the class with the specified name.
     * @exception LinkageError
     *            if the linkage fails
     * @exception ExceptionInInitializerError
     *            if the initialization provoked by this method fails
     * @exception ClassNotFoundException
     *            if the class cannot be located
     */
    public static Class<?> forName(String className) throws ClassNotFoundException {
        throw new RuntimeException();
    }

    /**
     * Casts this {@code Class} object to represent a subclass of the class
     * represented by the specified class object. Checks that the cast is valid, and
     * throws a {@code ClassCastException} if it is not. If this method succeeds, it
     * always returns a reference to this class object.
     *
     * <p>
     * This method is useful when a client needs to "narrow" the type of a
     * {@code Class} object to pass it to an API that restricts the {@code Class}
     * objects that it is willing to accept. A cast would generate a compile-time
     * warning, as the correctness of the cast could not be checked at runtime
     * (because generic types are implemented by erasure).
     *
     * @param clazz
     *            the class of the type to cast this class object to.
     * @return this {@code Class} object, cast to represent a subclass of the
     *         specified class object.
     * @throws ClassCastException
     *             if this {@code Class} object does not represent a subclass of the
     *             specified class (here "subclass" includes the class itself).
     * @param <U>
     * 			the type to cast this class object to
     */
    public <U> Class<? extends U> asSubclass(Class<U> clazz) {
        throw new RuntimeException();
    }

    /**
     * Casts an object to the class or interface represented by this {@code Class} object.
     *
     * @param obj
     *        the object to be cast
     * @return the object after casting, or null if obj is null
     *
     * @throws ClassCastException
     *         if the object is not null and is not assignable to the type T.
     */
    @Nullable
    public T cast(@Nullable Object obj) {
        throw new RuntimeException();
    }

    /**
     * Returns the assertion status that would be assigned to this class if it were to be initialized at
     * the time this method is invoked. If this class has had its assertion status set, the most recent
     * setting will be returned; otherwise, if any package default assertion status pertains to this
     * class, the most recent setting for the most specific pertinent package default assertion status
     * is returned; otherwise, the system class default assertion status is returned.
     * <p>
     * Few programmers will have any need for this method; it is provided for the benefit of the JRE
     * itself. (It allows a class to determine at the time that it is initialized whether assertions
     * should be enabled.) Note that this method is not guaranteed to return the actual assertion status
     * that was (or will be) associated with the specified class when it was (or will be) initialized.
     *
     * @return the desired assertion status of the specified class.
     */
    public boolean desiredAssertionStatus() {
        throw new RuntimeException();
    }

    /**
     * Returns the name of the entity (class, interface, array class, primitive type, or void)
     * represented by this {@code Class} object, as a {@code String}.
     *
     * <p>
     * If this class object represents a reference type that is not an array type then the binary name
     * of the class is returned, as specified by <cite>The Java&trade; Language Specification</cite>.
     *
     * <p>
     * If this class object represents a primitive type or void, then the name returned is a
     * {@code String} equal to the Java language keyword corresponding to the primitive type or void.
     *
     * <p>
     * If this class object represents a class of arrays, then the internal form of the name consists of
     * the name of the element type preceded by one or more '{@code [}' characters representing the
     * depth of the array nesting. The encoding of element type names is as follows:
     *
     * <blockquote>
     * <table>
     * <caption style="visibility: collapse;">no_caption</caption>
     * <tr>
     * <th>Element Type
     * <th>&nbsp;&nbsp;&nbsp;
     * <th>Encoding
     * <tr>
     * <td>boolean
     * <td>&nbsp;&nbsp;&nbsp;
     * <td style="text-align: center">Z
     * <tr>
     * <td>byte
     * <td>&nbsp;&nbsp;&nbsp;
     * <td style="text-align: center">B
     * <tr>
     * <td>char
     * <td>&nbsp;&nbsp;&nbsp;
     * <td style="text-align: center">C
     * <tr>
     * <td>class or interface
     * <td>&nbsp;&nbsp;&nbsp;
     * <td style="text-align: center">L<i>classname</i>;
     * <tr>
     * <td>double
     * <td>&nbsp;&nbsp;&nbsp;
     * <td style="text-align: center">D
     * <tr>
     * <td>float
     * <td>&nbsp;&nbsp;&nbsp;
     * <td style="text-align: center">F
     * <tr>
     * <td>int
     * <td>&nbsp;&nbsp;&nbsp;
     * <td style="text-align: center">I
     * <tr>
     * <td>long
     * <td>&nbsp;&nbsp;&nbsp;
     * <td style="text-align: center">J
     * <tr>
     * <td>short
     * <td>&nbsp;&nbsp;&nbsp;
     * <td style="text-align: center">S
     * </table>
     * </blockquote>
     *
     * <p>
     * The class or interface name <i>classname</i> is the binary name of the class specified above.
     *
     * <p>
     * Examples: <blockquote>
     *
     * <pre>
     * String.class.getName()
     *     returns "java.lang.String"
     * (new Object[3]).getClass().getName()
     *     returns "[Ljava.lang.Object;"
     * (new int[3][4][5][6][7][8][9]).getClass().getName()
     *     returns "[[[[[[[I"
     * </pre>
     *
     * </blockquote>
     *
     * @return the name of the class or interface represented by this object.
     */
    public String getName() {
        throw new RuntimeException();
    }

    /**
     * Gets the package for this class. Null is returned if no package object was created by the class
     * loader of this class.
     *
     * @return the package of the class, or null if no package information is available from the archive
     *         or codebase.
     */
    @Nullable
    public Package getPackage() {
        throw new RuntimeException();
    }

    /**
     * Finds a resource with a given name.
     *
     * <p>
     * Before delegation, an absolute resource name is constructed from the given resource name using
     * this algorithm:
     *
     * <ul>
     *
     * <li>If the {@code name} begins with a {@code '/'} (<code>'&#92;u002f'</code> ), then the absolute
     * name of the resource is the portion of the {@code name} following the {@code '/'}.
     *
     * <li>Otherwise, the absolute name is of the following form:
     *
     * <blockquote> {@code modified_package_name/name} </blockquote>
     *
     * <p>
     * Where the {@code modified_package_name} is the package name of this object with {@code '/'}
     * substituted for {@code '.'} ( <code>'&#92;u002e'</code>).
     *
     * </ul>
     *
     * @param name
     *        name of the desired resource
     * @return A {@link java.io.InputStream} object or {@code null} if no resource with this name is
     *         found
     * @throws NullPointerException
     *         If {@code name} is {@code null}
     */
    @Nullable
    public InputStream getResourceAsStream(String name) {
        throw new RuntimeException();
    }

    /**
     * Returns the simple name of the underlying class as given in the source code. Returns an empty
     * string if the underlying class is anonymous.
     *
     * <p>
     * The simple name of an array is the simple name of the component type with "[]" appended. In
     * particular the simple name of an array whose component type is anonymous is "[]".
     *
     * @return the simple name of the underlying class
     */
    public String getSimpleName() {
        throw new RuntimeException();
    }

    /**
     * Returns the {@code Class} representing the superclass of the entity (class, interface, primitive
     * type or void) represented by this {@code Class}. If this {@code Class} represents either the
     * {@code Object} class, an interface, a primitive type, or void, then null is returned. If this
     * object represents an array class then the {@code Class} object representing the {@code Object}
     * class is returned.
     *
     * @return the superclass of the class represented by this object.
     */
    @Nullable
    public Class<? super T> getSuperclass() {
        throw new RuntimeException();
    }

    /**
     * Determines if this {@code Class} object represents an array class.
     *
     * @return {@code true} if this object represents an array class; {@code false} otherwise.
     */
    public boolean isArray() {
        throw new RuntimeException();
    }

    /**
     * Determines if the class or interface represented by this {@code Class} object is either the same
     * as, or is a superclass or superinterface of, the class or interface represented by the specified
     * {@code Class} parameter. It returns {@code true} if so; otherwise it returns {@code false}. If
     * this {@code Class} object represents a primitive type, this method returns {@code true} if the
     * specified {@code Class} parameter is exactly this {@code Class} object; otherwise it returns
     * {@code false}.
     *
     * <p>
     * Specifically, this method tests whether the type represented by the specified {@code Class}
     * parameter can be converted to the type represented by this {@code Class} object via an identity
     * conversion or via a widening reference conversion. See <em>The Java Language Specification</em>,
     * sections 5.1.1 and 5.1.4 , for details.
     *
     * @param cls
     *        the {@code Class} object to be checked
     * @return the {@code boolean} value indicating whether objects of the type {@code cls} can be
     *         assigned to objects of this class
     * @exception NullPointerException
     *            if the specified Class parameter is null.
     */
    public boolean isAssignableFrom(Class<?> cls) {
        throw new RuntimeException();
    }

    /**
     * Determines if the specified {@code Object} is assignment-compatible with the object represented
     * by this {@code Class}. This method is the dynamic equivalent of the Java language
     * {@code instanceof} operator. The method returns {@code true} if the specified {@code Object}
     * argument is non-null and can be cast to the reference type represented by this {@code Class}
     * object without raising a {@code ClassCastException.} It returns {@code false} otherwise.
     *
     * <p>
     * Specifically, if this {@code Class} object represents a declared class, this method returns
     * {@code true} if the specified {@code Object} argument is an instance of the represented class (or
     * of any of its subclasses); it returns {@code false} otherwise. If this {@code Class} object
     * represents an array class, this method returns {@code true} if the specified {@code Object}
     * argument can be converted to an object of the array class by an identity conversion or by a
     * widening reference conversion; it returns {@code false} otherwise. If this {@code Class} object
     * represents an interface, this method returns {@code true} if the class or any superclass of the
     * specified {@code Object} argument implements this interface; it returns {@code false} otherwise.
     * If this {@code Class} object represents a primitive type, this method returns {@code false}.
     *
     * @param obj
     *        the object to check
     * @return true if {@code obj} is an instance of this class
     */
    public boolean isInstance(@Nullable Object obj) {
        throw new RuntimeException();
    }

    /**
     * Determines if the specified {@code Class} object represents an interface type.
     *
     * @return {@code true} if this object represents an interface; {@code false} otherwise.
     */
    public boolean isInterface() {
        throw new RuntimeException();
    }

    /**
     * Creates a new instance of the class represented by this {@code Class} object. The class is
     * instantiated as if by a {@code new} expression with an empty argument list. The class is
     * initialized if it has not already been initialized.
     *
     * @return a newly allocated instance of the class represented by this object.
     * @exception IllegalAccessException
     *            if the class or its nullary constructor is not accessible.
     * @exception InstantiationException
     *            if this {@code Class} represents an abstract class, an interface, an array class, a
     *            primitive type, or void; or if the class has no nullary constructor; or if the
     *            instantiation fails for some other reason.
     * @exception ExceptionInInitializerError
     *            if the initialization provoked by this method fails.
     */
    public T newInstance() throws InstantiationException, IllegalAccessException {
        throw new RuntimeException();
    }

    /**
     * Converts the object to a string. The string representation is the string "class" or "interface",
     * followed by a space, and then by the fully qualified name of the class in the format returned by
     * {@code getName}. If this {@code Class} object represents a primitive type, this method returns
     * the name of the primitive type. If this {@code Class} object represents void this method returns
     * "void".
     *
     * @return a string representation of this class object.
     */
    @Override
    public String toString() {
        throw new RuntimeException();
    }
}
