反射基礎
Class類
鋪墊動態代理
反射其他文章
傻瓜教你反射(二) ---- Constructor
傻瓜教你反射(三) ---- Field
傻瓜教你反射(四) ---- Method
1.定義
Java中,每個class都有一個相應的Class對象
(一個類->編譯完成->生成的.class文件->產生一個Class對象——用于表示這個類的類型信息)
Class類是一個final類
2.獲取Class實例
1)創建一個簡單的A類
package com.company;
public class A{
private String s;
public int b;
public A(){
System.out.println("A類無參數構造");
}
public A(String s){
System.out.println("A類有參數構造:s:"+s);
}
private A(int a){
System.out.println("A類有參數 私有構造:a:"+a);
}
public void show(){
}
}
2)如何獲得類A的Class實例
package com.company;
public class Reflect {
public static void main(String[] args) throws ClassNotFoundException {
/**
* 1.使用類的對象獲取
* 每個類都使用Object作為父類
* Object類方法getClass()返回這個類的class文件對象
* 方法返回值Class類型對象
*/
A a = new A();
Class classa = a.getClass();
System.out.println(classa);
/**
* 2.使用類的靜態屬性獲取
* 類名.class 返回這個類的class文件對象.屬性
* 運行結果也是Class類型對象
*/
Class classb = A.class;
System.out.println(classb);
/**
* 3.使用Class類的靜態方法獲取
* Class類靜態方法forName(String類名)[注意:全類名]
* 傳遞字符串類名獲取到這個類的class文件對象
* 方法返回值也是Class類型對象
*/
Class classc;
classc = Class.forName("com.company.A");//括號內需要一個字符串,所以要加引號
System.out.println(classc);
System.out.println(classa == classb);
System.out.println(classb == classc);
}
}
- 運行結果
A類無參數構造
class com.company.A
class com.company.A
class com.company.A
true
true
3.總結
方式 | 使用范圍 |
---|---|
getClass() | 需要獲取對象實例,僅能用于引用類型 |
.class | 無需獲取對象實例,既可以是引用類型也可以是基本類型 |
forName() | 只需要類的全限定名 |
基本類型(基本數據類型):
byte
int
short
long
float
double
char
boolean
;
引用類型:(除上述基本類型外,剩下的即為引用類型)引用類型是一種對象類型,它的值是指向內存空間的引用,就是地址
。Java有 5種引用類型(對象類型):類
接口
數組
枚舉
標注
。
4.補充
基本類型獲取Class實例,除了使用.Class,還可以通過基本類型的包裝類的TYPE字段:
Class a = Double.TYPE;
Class b = Void.TYPE;
5.提問
Q1
為什么基本類型無法用第一種和第三種方法獲取?
Q2
boolean怎么獲取Class嗎?
Q3
Class c = System.console().getClass();對嗎?
(答案在文章末尾,嘻嘻~)
6.鋪墊
java.lang.Class是所有反射操作的的入口,舉例:
getSupperClass() :返回指定的父類
Class.getClasses() :獲取所有內部所有public類,接口,枚舉,包括本身和繼承的成員類。
Class.getClassLoader() :每個class都有一個reference,指向自己的ClassLoader
/**
* 使用Class中的API
*/
Class cls = A.class//獲取Class實例
Object object = cls.getSupperClass();//以Class的實例為入口,使用其中的方法來獲得A類的父類
A1
因為第一種.getClass()基于每個類都使用Object作為父類,Object類方法getClass()返回這個類的class文件對象,但是基本類型是原生類型,并沒有Object作為父類
A2
boolean是原生類型,只能使用第二種方法獲取Class實例,Class bl = boolean.class或者用補充的方法 Class bl2 = boolean.TYPE
A3
正確,因為System.console()返回的是一個實例化對象(且不是原生類型(基本類型)的實例化對象)