Java程序在運行時,Java運行時系統一直對所有的對象進行所謂的運行時類型標識。 這項信息紀錄了每個對象所屬的類。虛擬機通常使用運行時類型信息選準正確方法去執行,用來保存這些類型信息的類是Class類。Class類封裝一個對象和接口運行時的狀態,當裝載類時,Class類型的對象自動創建。
一、類定義
public final class Class<T> implements java.io.Serializable,GenericDeclaration,Type,AnnotatedElement {}
- Serializable:可被序列化的標志接口
- GenericDeclaration:可以聲明(定義)范型變量
- Type:聲明用的表示這是一個表示Type的東西
- AnnotatedElement:表了在當前JVM中的一個“被注解元素”
二、常用方法
Class類沒有公共的構造方法,無法通過new運算符實例化;只能通過對象的getClass方法,或是通過Class.forName(…)來獲得實例。
1、getName()
一個Class對象描述了一個特定類的屬性,Class類中最常用的方法getName以 String 的形式返回此 Class 對象所表示的實體(類、接口、數組類、基本類型或 void)名稱。
public String getName() {String name = this.name;if (name == null)this.name = name = getName0();return name;}// cache the name to reduce the number of calls into the VMprivate transient String name;private native String getName0();
2、newInstance()
可以為類創建一個實例
@CallerSensitive
public T newInstance()throws InstantiationException, IllegalAccessException
{if (System.getSecurityManager() != null) {checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);}// NOTE: the following code may not be strictly correct under// the current Java memory model.// Constructor lookupif (cachedConstructor == null) {if (this == Class.class) {throw new IllegalAccessException("Can not call newInstance() on the Class for java.lang.Class");}try {Class<?>[] empty = {};final Constructor<T> c = getConstructor0(empty, Member.DECLARED);// Disable accessibility checks on the constructor// since we have to do the security check here anyway// (the stack depth is wrong for the Constructor's// security check to work)java.security.AccessController.doPrivileged(new java.security.PrivilegedAction<Void>() {public Void run() {c.setAccessible(true);return null;}});cachedConstructor = c;} catch (NoSuchMethodException e) {throw (InstantiationException)new InstantiationException(getName()).initCause(e);}}Constructor<T> tmpConstructor = cachedConstructor;// Security check (same as in java.lang.reflect.Constructor)int modifiers = tmpConstructor.getModifiers();if (!Reflection.quickCheckMemberAccess(this, modifiers)) {Class<?> caller = Reflection.getCallerClass();if (newInstanceCallerCache != caller) {Reflection.ensureMemberAccess(caller, this, null, modifiers);newInstanceCallerCache = caller;}}// Run constructortry {return tmpConstructor.newInstance((Object[])null);} catch (InvocationTargetException e) {Unsafe.getUnsafe().throwException(e.getTargetException());// Not reachedreturn null;}
}
private volatile transient Constructor<T> cachedConstructor;
private volatile transient Class<?> newInstanceCallerCache;
3、getClassLoader()
返回該類的類加載器。
@CallerSensitive
public ClassLoader getClassLoader() {ClassLoader cl = getClassLoader0();if (cl == null)return null;SecurityManager sm = System.getSecurityManager();if (sm != null) {ClassLoader.checkClassLoaderPermission(cl, Reflection.getCallerClass());}return cl;
4、getComponentType()
返回表示數組組件類型的 Class。
public native Class<?> getComponentType();
5、getSuperclass()
返回表示此 Class 所表示的實體(類、接口、基本類型或 void)的超類的 Class。
public native Class<? super T> getSuperclass();
6、isArray()
判定此 Class 對象是否表示一個數組類。
public native boolean isArray();
7、getSimpleName()
返回源代碼中給出的基礎類的簡稱。string
public String getSimpleName() {if (isArray())return getComponentType().getSimpleName()+"[]";String simpleName = getSimpleBinaryName();if (simpleName == null) { // top level classsimpleName = getName();return simpleName.substring(simpleName.lastIndexOf(".")+1); // strip the package name}int length = simpleName.length();if (length < 1 || simpleName.charAt(0) != '$')throw new InternalError("Malformed class name");int index = 1;while (index < length && isAsciiDigit(simpleName.charAt(index)))index++;// Eventually, this is the empty string iff this is an anonymous classreturn simpleName.substring(index);
}
8、getDeclaredFields()
返回 Field
對象的一個數組,這些對象反映此 Class
對象所表示的類或接口所聲明的所有字段。
@CallerSensitive
public Field[] getDeclaredFields() throws SecurityException {checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);return copyFields(privateGetDeclaredFields(false));
}
java.lang.reflect.Field主要是用于反射類的字段。反射經常用于工具類的開發,或中間件的開發。
三、總結
Class 沒有公共構造方法。Class 對象是在加載類時由 Java 虛擬機以及通過調用類加載器中的 defineClass 方法自動構造的,因此不能顯式地聲明一個Class對象。
虛擬機為每種類型管理一個獨一無二的Class對象。也就是說,每個類(型)都有一個Class對象。運行程序時,Java虛擬機(JVM)首先檢查是否 所要加載的類對應的Class對象是否已經加載。如果沒有加載,JVM就會根據類名查找.class文件,并將其Class對象載入。
基本的 Java 類型(boolean、byte、char、short、int、long、float 和 double)和關鍵字 void 也都對應一個 Class 對象。
每個數組屬于被映射為 Class 對象的一個類,所有具有相同元素類型和維數的數組都共享該 Class 對象。
一般某個類的Class對象被載入內存,它就用來創建這個類的所有對象。