前言
Class類是一個看起來熟悉又看起來陌生的類,平時常常用到它,但卻從來沒有創建過它的實例對象,因爲它的構造函數是私有的,只有虛擬機才能夠創建它的對象,但是它絕對是一個核心類,以至於要學好java就必須要精通它,希望我的理解可以對你有所幫助。
Class類是什麼
(1)它是一個類,存在於java.lang包中,它的構造函數是私有的,由JVM(類加載器)創建Class對象,我們可以通過getClass()方法獲取到Class對象。
/*
* 私有構造函數,使得只有jvm可以創建該類的對象,這個私有構造函數還可以防止通過默認構造函數創建類對象
*/
private Class(ClassLoader loader) {
// 初始化final變量ClassLoader
classLoader = loader;
}
(2)Class對象,通過它我們可以拿到創建的類的屬性,方法等。
Class類的作用
(1)獲取類中屬性的類型
(2)獲取類中屬性的名稱
(3)獲取類的方法
(4)獲取類的基類等等
(5)綜合上述可以利用它完成反射
Class的主要方法
1.forName方法
輸入需要加載的類的全路徑名,得到類的Class對象
2.newInstance方法
public T newInstance()
throws InstantiationException, IllegalAccessException
{
if (System.getSecurityManager() != null) {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
}
// NOTE: 下面的編碼可能不是嚴格符合當前的java內存模型
// 尋找構造器
if (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);
// 設置構造器允許訪問
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;
// 安全檢查
int modifiers = tmpConstructor.getModifiers();
if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
if (newInstanceCallerCache != caller) {
Reflection.ensureMemberAccess(caller, this, null, modifiers);
newInstanceCallerCache = caller;
}
}
// 執行無參構造函數創建實例對象
try {
return tmpConstructor.newInstance((Object[])null);
} catch (InvocationTargetException e) {
Unsafe.getUnsafe().throwException(e.getTargetException());
// Not reached
return null;
}
}
3.isInstance(native方法)
用於判斷入參是否爲當前Class對象(子類)的實現類
public class TestInfo {
static {
System.out.println("我是誰");
}
public TestInfo(){
System.out.println("我是構造函數");
}
public String test="測試屬性";
public static void main(String[] args) {
TestClass info=new TestClass();
//返回結果是true因爲info是子類的對象
System.out.println(TestInfo.class.isInstance(info));
}
public static class TestClass extends TestInfo{
}
}
4.getName、getTypeName、getCanonicalName、getSimpleName
public static void main(String[] args) {
System.out.println(TestClass.class.getTypeName());
System.out.println(TestClass.class.getCanonicalName());
System.out.println(TestClass.class.getSimpleName());
System.out.println(TestClass.class.getName());
System.out.println("-------------------------------------------------------");
System.out.println(TestClass[].class.getTypeName());
System.out.println(TestClass[].class.getCanonicalName());
System.out.println(TestClass[].class.getSimpleName());
System.out.println(TestClass[].class.getName());
}
public static abstract class TestClass<T extends TestInfo, String> extends TestInfo implements Aware, Comparable<Integer> {
public abstract void test();
}
輸出結果
com.hikvision.test.abc.TestInfo$TestClass
com.hikvision.test.abc.TestInfo.TestClass
TestClass
com.hikvision.test.abc.TestInfo$TestClass
-------------------------------------------------------
com.hikvision.test.abc.TestInfo$TestClass[]
com.hikvision.test.abc.TestInfo.TestClass[]
TestClass[]
[Lcom.hikvision.test.abc.TestInfo$TestClass;
5.getClassLoader
獲取當前類的類加載器
6.getTypeParameters
獲取泛型類中的泛型參數數組。
7.getSuperclass和getGenericSuperclass
都是獲取父類信息,但是後者會帶上泛型參數
8.getInterfaces和getGenericInterfaces
獲取當前Class對象實現的接口數組,但是後者會帶上接口的泛型參數,如
public static void main(String[] args) {
System.out.println(TestClass.class.getInterfaces()[1]);
}
public static abstract class TestClass<T extends TestInfo,String> extends TestInfo implements Aware,BeanFactory {
public abstract void test();
}
輸出結果
interface org.springframework.beans.factory.BeanFactory
java.lang.Comparable<java.lang.Integer>
9.isAssignableFrom(native方法)
這個方法比較反人類,括號裏的入參表示的是當前Class對象的父類或者是同一個對象時才成立。
//這樣返回的是false
System.out.println(TestClass.class.isAssignableFrom(TestInfo.class));
10.isInterface(native方法)
判斷是否爲接口
11.isArray(native方法)
是否爲數組
12.isPrimitive(native方法)
用於判斷這個Class對象是否爲基本類型,如int,byte,char等
13.isAnnotation
判斷這個Class對象是否爲註解
14.getComponentType
如果當前Class對象是數組,獲取數組中的元素類型
15.getModifiers
獲取屬性或方法前面的修飾詞對應的枚舉值
16.getDeclaringClass
獲取方法或屬性的歸屬類,或者獲取當前Class對象繼承於哪個類
17.getSimpleName
Class對象的類名
18.getClasses、getDeclaredClasses
(1)獲取Class對象中public修飾的內部類
(2)獲取Class對象中的內部類,繼承成員是不包含在內的
19.getFields、getField、getDeclaredFields
(1)獲取public修飾的屬性域
(2)根據輸入的屬性名查找對應的屬性域
(3)獲取Class對象中的屬性域
20.getMethods、getMethod、getDeclaredMethods
(1)獲取public修飾的方法
(2)根據輸入的方法名和入參類型,查找對應的方法
(3)獲取Class對象中的方法
21.getConstructors、getConstructor、getDeclaredConstructors
(1)獲取public修飾的構造函數
(2)根據輸入的方法名和入參類型,查找對應的構造函數
(3)獲取Class對象中的構造函數
最後
類裏面還有很多名稱類似的方法,可以根據上述說明推測出他們的功能,還有一些不常用的方法,這裏就不列舉了