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 {

	private Class() {
		// This class cannot be instantiated.
		throw new RuntimeException();
	}
	
	/**
	 * 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();
	}

}
