常用的几种取得Class类实例的方式:
1 class literal (class字面量, 如String.class/int.class/void.class)
2 instanceOfClass.getClass();
3 Class.forName(String className)
4 classLoaderInstance.loadClass(String name, boolean resolve)
3 4 为显式的动态加载,关于动态加载,我要
记得看附件中的Understanding Class.forName.pdf!关于ClassLoader的更多知识参阅
http://wuaner.iteye.com/admin/blogs/1011036,这里不再详述。
class literal:
Java Language Specification -> 15.8.2 Class Literals :
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.8.2
引用
A class literal is an expression consisting of the name of a class, interface, array, or primitive type, or the pseudo-type void, followed by a '.' and the token class.
The type of C.class, where C is the name of a class, interface, or array type (§4.3), is Class<C>.
The type of p.class, where p is the name of a primitive type (§4.2), is Class<B>, where B is the type of an expression of type p after boxing conversion (§5.1.7).
The type of void.class (§8.4.5) is Class<Void>.
class字面量只能作用在type名上(这里的type包括class, interface, array, primitive type,void)!Object的方法getClass()作用在类实例上!它们返回的都是Class类的实例!
对一个Class类的实例clazz,可以一直调用getClass方法!而.class因为不能作用在类实例上,所以不能一直调下去,因为第一次调SomeClass.class时,返回的就已经是个Class类的实例了!
JDK中关于Class类:
引用
public final class Class<T>
extends Object
implements Serializable, GenericDeclaration, Type, AnnotatedElement
Instances of the class 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 Class object that is shared by all arrays with the same element type and number of dimensions. The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects.
Class has no public constructor. Instead Class objects are constructed automatically by the Java Virtual Machine as classes are loaded and by calls to the defineClass method in the class loader.
The following example uses a Class object to print the class name of an object:
void printClassName(Object obj) {
System.out.println("The class of " + obj +
" is " + obj.getClass().getName());
}
It is also possible to get the Class object for a named type (or for void) using a class literal (JLS Section 15.8.2). For example:
System.out.println("The name of class Foo is: "+Foo.class.getName());
关于Class.forName():
引用
public static Class<?> forName(String name,
boolean initialize,
ClassLoader loader)
throws ClassNotFoundException
Returns the Class object associated with the class or interface with the given string name, using the given class loader. Given the fully qualified name for a class or interface (in the same format returned by getName) this method attempts to locate, load, and link the class or interface. The specified class loader is used to load the class or interface. If the parameter loader is null, the class is loaded through the bootstrap class loader. The class is initialized only if the initialize parameter is true and if it has not been initialized earlier.
If name denotes a primitive type or void, an attempt will be made to locate a user-defined class in the unnamed package whose name is name. Therefore, this method cannot be used to obtain any of the Class objects representing primitive types or void.
If name denotes an array class, the component type of the array class is loaded but not initialized.
For example, in an instance method the expression:
Class.forName("Foo")
is equivalent to:
Class.forName("Foo", true, this.getClass().getClassLoader())
Note that this method throws errors related to loading, linking or initializing as specified in Sections 12.2, 12.3 and 12.4 of The Java Language Specification. Note that this method does not check whether the requested class is accessible to its caller.
If the loader is null, and a security manager is present, and the caller's class loader is not null, then this method calls the security manager's checkPermission method with a RuntimePermission("getClassLoader") permission to ensure it's ok to access the bootstrap class loader.
Parameters:
name - fully qualified name of the desired class
initialize - whether the class must be initialized
loader - class loader from which the class must be loaded
Returns:
class object representing the desired class
使用clazz(a instance of Class).newInstance()时要注意:
引用
if this 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,将会抛出InstantiationException
关于Object的getClass() 方法:
引用
public final Class<?> getClass()
Returns the runtime class of this Object. The returned Class object is the object that is locked by static synchronized methods of the represented class.
The actual result type is Class<? extends |X|> where |X| is the erasure of the static type of the expression on which getClass is called. For example, no cast is required in this code fragment:
Number n = 0;
Class<? extends Number> c = n.getClass();
Returns:
The Class object that represents the runtime class of this object.
What is a class literal in Java ?
http://stackoverflow.com/questions/2160788/what-is-a-class-literal-in-java
Understanding Class.forName()(请见附件pdf文档):
http://www.theserverside.com/news/1365412/Understanding-ClassforName-Java
例子:
public class Parent {
public static void main(String[] args) throws Exception {
Class c1 = void.class;
Class c2 = int.class;
Class c3 = Integer.class;
System.out.println(c2 == c3); //false
//Integer i = (Integer)c3.newInstance(); //会报InstantiationException,原因是Integer没有无参构造方法
Class clazz1 = String.class;
String string = (String)clazz1.newInstance();
string = "ooo";
System.out.println(string);
Class clazz2 = Class.class;
///Class clazz3 = Class.forName("package.MyClass"); //必须处理ClassNotFoundException
String str = "abc";
Class clazz4 = str.getClass();
Class clazz5 = clazz1.getClass().getClass().getClass();
//Class clazz6 = String.class.class; //编译错误
Class clazz7 = System.out.getClass().getClass();
//Class clazz8 = System.out.class; //编译错误
System.out.println(String.class == "abc".getClass()); //true
System.out.println(Class.class == clazz1.getClass()); //true
System.out.println(Class.class == clazz4.getClass()); //true
System.out.println(String.class == "abc".getClass().getClass()); //false
System.out.println(Class.class == clazz7.getClass().getClass()); //true
Parent p = new Parent();
System.out.println(p.getClass() == Parent.class); //true
System.out.println(p.getClass().getClass() == Parent.class); //false
Parent p2 = new Child();
System.out.println(p2.getClass() == Parent.class); //false
System.out.println(p2.getClass() == Child.class); //true
System.out.println(p2.getClass().getClass() == Child.class); //false
//System.out.println(String.class == Parent.class); //编译错误:Incompatible operand types Class<String> and Class<Parent>
System.out.println("abc".getClass() == p.getClass()); //false
}
}
class Child extends Parent {
}
http://juixe.com/techknow/index.php/2006/05/08/javaclass/
引用
In Java, given an object, an instance of a class, you can get the class name by coding the following:
Class clazz = obj.getClass();
String clazzName = clazz.getName();
Sometimes you want you want to create a Class object for a given class. In this case you can do so by writing code similar to the following example:
Class clazz = MyClass.class;
Many plugin frameworks, including the JDBC Driver Manager will create a Class object without having the knowledge of what class name at compile time. There might be a case where you know a class implements a given interface but you don’t know the class name of the implementation until at runtime when you read it from a properties file. In situations like this you can do the following:
String clazzName = "com.juixe.techknow.MyClass";
...
Class clazz = Class.forName(clazzName);
Sometimes you will need a Class object for a primitive type. You might need a Class object for an int or boolean when dealing with reflection. In this case you do so using the dot class notation on a primitive type. Here is a more elaborate example where we create a Class object for an int primitive:
int newValue = ...
Class clazz = obj.getClass();
Method meth = clazz.getMethod("setValue", new Class[]{int.class});
meth.invoke(obj, new Object[]{new Integer(newValue)});
You can also get the class for an array. The only place where I have ever need the class of an array is when working with reflection. Here is how you can get the class for an array:
Class clazz = String[].class;