Class類(lèi)與JAVA反射
通過(guò)反射可以訪問(wèn)的主要信息
包路徑
getPackage() Package對(duì)象 獲取該對(duì)象的存放路徑;
類(lèi)名稱(chēng)
getName() String對(duì)象 獲得該類(lèi)的名稱(chēng);
繼承類(lèi)
getSuperclass() Class對(duì)象 獲得該類(lèi)的繼承的類(lèi);
實(shí)現(xiàn)接口類(lèi)
getInterface() Class型數(shù)組 獲取該類(lèi)實(shí)現(xiàn)的所有接口;
構(gòu)造方法
getConstructors() Constructors型數(shù)組 獲得所有權(quán)限為public的構(gòu)造方法;
getConstructor(Class<?>...parameterTypes) Constructors 獲得權(quán)限為public的指定構(gòu)造方法;
getDeclaredConstructor() Constructors型數(shù)組 獲得所有狗做方法,按生命順序返回;
getDeclaredConstructor(Class<?>...parameterTypes) Constructors對(duì)象 獲得指定構(gòu)造法方法;
方法
getMethods() Method型數(shù)組 獲得所有public權(quán)限的方法;
getMethod(String name,Class<?>...parameterTypes) Method對(duì)象 獲得權(quán)限為public的指定方法;
getDeclaredMethods() Method型數(shù)組 獲得所有方法,按聲明順序返回;
getDeclaredMethod(String name,Class<?>...parameterTypes) Method對(duì)象,獲得指定的方法;
成員變量
getFields() Field型數(shù)組 獲得所有權(quán)限為public的成員變量;
getField(String name) Field對(duì)象 活動(dòng)權(quán)限為public的指定成員變量;
getDeclaredFields() Field型數(shù)組 獲得所有成員變量,按聲明順序返回;
getDeclaredField(String name) Field對(duì)象 獲得指定的成員變量;
內(nèi)部類(lèi)
getClasses() Class型數(shù)組 獲得所有權(quán)限為public的內(nèi)部類(lèi);
getDeclaredClasses() Class型數(shù)組 獲得所有內(nèi)部類(lèi);
內(nèi)部類(lèi)的聲明類(lèi) getDeclaringClass() Class對(duì)象 如果該類(lèi)為內(nèi)部類(lèi),則返回它的成員類(lèi),否則返回NULL;
在通過(guò)getFields()和getMethods()方法時(shí),將包含從超類(lèi)繼承道德成員變量和方法;而通過(guò) getDeclaredFields() 和 getDeclaredMethods() 只能獲得在奔雷定義的所有成員變量和方
訪問(wèn)構(gòu)造方法
isVarArgs() 查看該構(gòu)造方法是否允許帶有可變數(shù)量的參數(shù),如果允許則返回true,否則false;
getParameterTypes() 按照聲明順序以Class數(shù)組的形式獲得該構(gòu)造方法的各個(gè)參數(shù)類(lèi)型;
getExceptionTypes() 以Class數(shù)組的形式獲得該構(gòu)造方法可能拋出的異常類(lèi)型。
newInstance(Object...initargs) 通過(guò)該構(gòu)造方法利用指定構(gòu)造方法創(chuàng)建一個(gè)該類(lèi)的對(duì)象,如果未設(shè)置,則采用無(wú)參默認(rèn)構(gòu)造函數(shù)
setAccessible(boolean flag) 針對(duì)private的構(gòu)造方法 限制性該方法設(shè)置為true,則可以使用newInstance(Object...initargs)創(chuàng)建對(duì)象;
getModifiers() 獲得可以解析出該構(gòu)造方法所采用修飾符的整數(shù);
public class ClassEntity {
String s;
int i, i2, i3;
private ClassEntity() {
}
protected ClassEntity(String s, int i) {
this.s = s;
this.i = i;
}
public ClassEntity(String... strings) throws NumberFormatException {
if (0 < strings.length)
i = Integer.valueOf(strings[0]);
if (1 < strings.length)
i2 = Integer.valueOf(strings[1]);
if (2 < strings.length)
i3 = Integer.valueOf(strings[2]);
}
public void print() {
System.out.println("s=" + s);
System.out.println("i=" + i);
System.out.println("i2=" + i2);
System.out.println("i3=" + i3);
}
}
public static void main(String[] args) {
ClassEntity example = new ClassEntity("10", "20", "30");
Class<? extends ClassEntity> exampleC = example.getClass();
Constructor[] declaredConstructors = exampleC.getDeclaredConstructors();
for (int i = 0; i < declaredConstructors.length; i++) {
Constructor<?> constructor = declaredConstructors[i];
System.out.println("查看是否允許帶有可變數(shù)量的參數(shù):" + constructor.isVarArgs());
System.out.println("該構(gòu)造方法的入口參數(shù)類(lèi)型依次為:");
Class[] parameterTypes = constructor.getParameterTypes();
for (int j = 0; j < parameterTypes.length; j++) {
System.out.println(" " + parameterTypes[j]);
}
System.out.println("該構(gòu)造方法可能拋出的異常類(lèi)型為:");
Class[] exceptionTypes = constructor.getExceptionTypes();
for (int j = 0; j < exceptionTypes.length; j++) {
System.out.println(" " + exceptionTypes[j]);
}
ClassEntity example2 = null;
while (example2 == null) {
try {
if (i == 2)
example2 = (ClassEntity) constructor.newInstance();
else if (i == 1)
example2 = (ClassEntity) constructor.newInstance("7", 5);
else {
Object[] parameters = new Object[] { new String[] {
"100", "200", "300" } };
example2 = (ClassEntity) constructor
.newInstance(parameters);
}
} catch (Exception e) {
System.out.println("在創(chuàng)建對(duì)象時(shí)拋出異常,下面執(zhí)行setAccessible()方法");
constructor.setAccessible(true);
}
}
if(example2!=null){
example2.print();
System.out.println();
}
}
}
訪問(wèn)成員變量
getName() 獲得該成員變量的名稱(chēng);
getType() 獲得表示該成員變量類(lèi)型的Class對(duì)象;
get(Object o) 獲得指定對(duì)象obj中成員變量的值,返回Object類(lèi)型;
Set(Object o,Object value) 將指定對(duì)象obj成員變量設(shè)置value值;
getInt(Object o) ;
SetInt(Object o,int value) ;
...
setAccessible(boolean flage) 此方法可以設(shè)置是否忽略權(quán)限限制直接訪問(wèn)private等私有權(quán)限的成員變量;
getModifiers() 獲得可以解析出該成員變量所采用修飾符的整數(shù);
public class ClassFeildEntity {
int i;
public float f;
protected boolean b;
private String s;
// private ClassEntity classEntity;
}
public static void main(String[] args) {
ClassFeildEntity example = new ClassFeildEntity();
Class exampleC = example.getClass();
// 獲得所有成員變量
Field[] declaredFields = exampleC.getDeclaredFields();
for (int i = 0; i < declaredFields.length; i++) {
Field field = declaredFields[i]; // 遍歷成員變量
// 獲得成員變量名稱(chēng)
System.out.println("名稱(chēng)為:" + field.getName());
Class fieldType = field.getType(); // 獲得成員變量類(lèi)型
System.out.println("類(lèi)型為:" + fieldType);
boolean isTurn = true;
while (isTurn) {
// 如果該成員變量的訪問(wèn)權(quán)限為private,則拋出異常,即不允許訪問(wèn)
try {
isTurn = false;
// 獲得成員變量值
System.out.println("修改前的值為:" + field.get(example));
// 判斷成員變量的類(lèi)型是否為int型
if (fieldType.equals(int.class)) {
System.out.println("利用方法setInt()修改成員變量的值");
field.setInt(example, 168); // 為int型成員變量賦值
// 判斷成員變量的類(lèi)型是否為float型
} else if (fieldType.equals(float.class)) {
System.out.println("利用方法setFloat()修改成員變量的值");
// 為float型成員變量賦值
field.setFloat(example, 99.9F);
// 判斷成員變量的類(lèi)型是否為boolean型
} else if (fieldType.equals(boolean.class)) {
System.out.println("利用方法setBoolean()修改成員變量的值");
// 為boolean型成員變量賦值
field.setBoolean(example, true);
} else {
System.out.println("利用方法set()修改成員變量的值");
// 可以為各種類(lèi)型的成員變量賦值
field.set(example, "MWQ");
}
// 獲得成員變量值
System.out.println("修改后的值為:" + field.get(example));
} catch (Exception e) {
System.out.println("在設(shè)置成員變量值時(shí)拋出異常,"
+ "下面執(zhí)行setAccessible()方法!");
field.setAccessible(true); // 設(shè)置為允許訪問(wèn)
isTurn = true;
}
}
System.out.println();
}
}
訪問(wèn)方法
getName() 獲得該方法名稱(chēng);
getParameterTypes() 按照聲明順序以Class數(shù)組的形式獲得該方法的各個(gè)參數(shù)類(lèi)型;
getReturnType() 以Class對(duì)象的形式獲得該方法的返回值的類(lèi)型;
getExceptionTypes() 以class數(shù)組的形式獲得該方法可能跑出的異常類(lèi)型;
invoke(Object o,Object...args) 利用指定參數(shù)args執(zhí)行指定對(duì)象obj中的該方法,趕回值為Object 型;
isVarArgs() 查看該構(gòu)造方法是夠允許帶有可變數(shù)量的參數(shù),如果允許則返回true,否則返回false;
getModifiers() 獲得可以解析出該方法所采用修飾符的整數(shù);
setAccessible(boolean flage) ;
public class ClassMethodEntity {
static void staticMethod() {
System.out.println("執(zhí)行staticMethod()方法");
}
public int publicMethod(int i) {
System.out.println("執(zhí)行publicMethod()方法");
return i * 100;
}
protected int protectedMethod(String s, int i)
throws NumberFormatException {
System.out.println("執(zhí)行protectedMethod()方法");
return Integer.valueOf(s) + i;
}
private String privateMethod(String... strings) {
System.out.println("執(zhí)行privateMethod()方法");
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < strings.length; i++) {
stringBuffer.append(strings[i]);
}
return stringBuffer.toString();
}
}
public static void main(String[] args) {
ClassMethodEntity example = new ClassMethodEntity();
Class exampleC = example.getClass();
// 獲得所有方法
Method[] declaredMethods = exampleC.getDeclaredMethods();
for (int i = 0; i < declaredMethods.length; i++) {
Method method = declaredMethods[i]; // 遍歷方法
System.out.println("名稱(chēng)為:" + method.getName()); // 獲得方法名稱(chēng)
System.out.println("是否允許帶有可變數(shù)量的參數(shù):" + method.isVarArgs());
System.out.println("入口參數(shù)類(lèi)型依次為:");
// 獲得所有參數(shù)類(lèi)型
Class[] parameterTypes = method.getParameterTypes();
for (int j = 0; j < parameterTypes.length; j++) {
System.out.println(" " + parameterTypes[j]);
}
// 獲得方法返回值類(lèi)型
System.out.println("返回值類(lèi)型為:" + method.getReturnType());
System.out.println("可能拋出的異常類(lèi)型有:");
// 獲得方法可能拋出的所有異常類(lèi)型
Class[] exceptionTypes = method.getExceptionTypes();
for (int j = 0; j < exceptionTypes.length; j++) {
System.out.println(" " + exceptionTypes[j]);
}
boolean isTurn = true;
while (isTurn) {
// 如果該方法的訪問(wèn)權(quán)限為private,則拋出異常,即不允許訪問(wèn)
try {
isTurn = false;
if("staticMethod".equals(method.getName()))
method.invoke(example); // 執(zhí)行沒(méi)有入口參數(shù)的方法
else if("publicMethod".equals(method.getName()))
System.out.println("返回值為:"
+ method.invoke(example, 168)); // 執(zhí)行方法
else if("protectedMethod".equals(method.getName()))
System.out.println("返回值為:"
+ method.invoke(example, "7", 5)); // 執(zhí)行方法
else if("privateMethod".equals(method.getName())) {
Object[] parameters = new Object[] { new String[] {
"M", "W", "Q" } }; // 定義二維數(shù)組
System.out.println("返回值為:"
+ method.invoke(example, parameters));
}
} catch (Exception e) {
System.out.println("在執(zhí)行方法時(shí)拋出異常,"
+ "下面執(zhí)行setAccessible()方法!");
method.setAccessible(true); // 設(shè)置為允許訪問(wèn)
isTurn = true;
}
}
System.out.println();
}
}
Annotation功能
@Targer的枚舉常量
ANNOTATION_TYPE 表示用于annotation類(lèi)型;
TYPE 表示用于類(lèi),接口和枚舉,以及annotation類(lèi)型;
CONSTRUCTOR 表示用于構(gòu)造方法;
FIELD 表示用于成員變量和枚舉常量;
METHOD 表示用于方法;
PARAMETER 表示用于參數(shù);
LOCAL_VARLABLE 表示用于局部變量;
PACKAGE 表示用于包;
@Retention
SOURCE 表示不便于Annotaion到類(lèi)文件中;
CLASS 表示編譯到Annotation類(lèi)文件中,但是在運(yùn)行時(shí)不加載Annotation到j(luò)vm中;
RUNTIME 表示在運(yùn)行時(shí)加載Annotation到j(luò)vm中;
isAnnotation(Class<?extends Annotation> annotationClass) 用來(lái)查看是否添加了指定類(lèi)型的Annotation;
getAnnotation(Class<T> annotationClass) 用來(lái)獲得指定類(lèi)型的Annotation;
getParameterAnnotation() 用來(lái)獲得所有參數(shù)添加的Annotation,將以Annotation類(lèi)的二維數(shù)組返回;
@Target(ElementType.CONSTRUCTOR)
@Retention(RetentionPolicy.RUNTIME)
public @interface Constructor_Annotation {
String value() default "默認(rèn)構(gòu)造方法";
}
@Target( { ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface Field_Method_Parameter_Annotation {
String describe();
Class type() default void.class;
}
public class Record {
@Field_Method_Parameter_Annotation(describe = "編號(hào)", type = int.class)
int id;
@Field_Method_Parameter_Annotation(describe = "姓名", type = String.class)
String name;
@Constructor_Annotation()
public Record() {
}
@Constructor_Annotation("立即初始化構(gòu)造方法")
public Record(
@Field_Method_Parameter_Annotation(describe = "編號(hào)", type = int.class)
int id,
@Field_Method_Parameter_Annotation(describe = "姓名", type = String.class)
String name) {
this.id = id;
this.name = name;
}
@Field_Method_Parameter_Annotation(describe = "獲得編號(hào)", type = int.class)
public int getId() {
return id;
}
@Field_Method_Parameter_Annotation(describe = "設(shè)置編號(hào)")
public void setId(
@Field_Method_Parameter_Annotation(describe = "編號(hào)", type = int.class)
int id) {
this.id = id;
}
@Field_Method_Parameter_Annotation(describe = "獲得姓名", type = String.class)
public String getName() {
return name;
}
@Field_Method_Parameter_Annotation(describe = "設(shè)置姓名")
public void setName(
@Field_Method_Parameter_Annotation(describe = "姓名", type = String.class)
String name) {
this.name = name;
}
}
public static void main(String[] args) {
Class recordC = null;
try {
recordC = Class.forName("com.luozy.base.ClassDemo.AnnotationDemo.Record");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("------ 構(gòu)造方法的描述如下 ------");
Constructor[] declaredConstructors = recordC
.getDeclaredConstructors(); // 獲得所有構(gòu)造方法
for (int i = 0; i < declaredConstructors.length; i++) {
Constructor constructor = declaredConstructors[i]; // 遍歷構(gòu)造方法
// 查看是否具有指定類(lèi)型的注釋
if (constructor
.isAnnotationPresent(Constructor_Annotation.class)) {
// 獲得指定類(lèi)型的注釋
Constructor_Annotation ca = (Constructor_Annotation) constructor
.getAnnotation(Constructor_Annotation.class);
System.out.println(constructor.getName()+"構(gòu)造方法的注釋信息------"+ca.value()); // 獲得注釋信息
}
Annotation[][] parameterAnnotations = constructor
.getParameterAnnotations(); // 獲得參數(shù)的注釋
for (int j = 0; j < parameterAnnotations.length; j++) {
// 獲得指定參數(shù)注釋的長(zhǎng)度
int length = parameterAnnotations[j].length;
if (length == 0) // 如果長(zhǎng)度為0則表示沒(méi)有為該參數(shù)添加注釋
System.out.println(" 未添加Annotation的參數(shù)");
else
for (int k = 0; k < length; k++) {
// 獲得參數(shù)的注釋
Field_Method_Parameter_Annotation pa = (Field_Method_Parameter_Annotation) parameterAnnotations[j][k];
System.out.print(" " + pa.describe()); // 獲得參數(shù)描述
System.out.println(" " + pa.type()); // 獲得參數(shù)類(lèi)型
}
}
System.out.println();
}
System.out.println();
System.out.println("-------- 字段的描述如下 --------");
Field[] declaredFields = recordC.getDeclaredFields(); // 獲得所有字段
for (int i = 0; i < declaredFields.length; i++) {
Field field = declaredFields[i]; // 遍歷字段
// 查看是否具有指定類(lèi)型的注釋
if (field
.isAnnotationPresent(Field_Method_Parameter_Annotation.class)) {
// 獲得指定類(lèi)型的注釋
Field_Method_Parameter_Annotation fa = field
.getAnnotation(Field_Method_Parameter_Annotation.class);
System.out.print(" " + fa.describe()); // 獲得字段的描述
System.out.println(" " + fa.type()); // 獲得字段的類(lèi)型
}
}
System.out.println();
System.out.println("-------- 方法的描述如下 --------");
Method[] methods = recordC.getDeclaredMethods(); // 獲得所有方法
for (int i = 0; i < methods.length; i++) {
Method method = methods[i]; // 遍歷方法
// 查看是否具有指定類(lèi)型的注釋
if (method
.isAnnotationPresent(Field_Method_Parameter_Annotation.class)) {
// 獲得指定類(lèi)型的注釋
Field_Method_Parameter_Annotation ma = method
.getAnnotation(Field_Method_Parameter_Annotation.class);
System.out.println(ma.describe()); // 獲得方法的描述
System.out.println(ma.type()); // 獲得方法的返回值類(lèi)型
}
Annotation[][] parameterAnnotations = method
.getParameterAnnotations(); // 獲得參數(shù)的注釋
for (int j = 0; j < parameterAnnotations.length; j++) {
int length = parameterAnnotations[j].length; // 獲得指定參數(shù)注釋的長(zhǎng)度
if (length == 0) // 如果長(zhǎng)度為0表示沒(méi)有為該參數(shù)添加注釋
System.out.println(" 未添加Annotation的參數(shù)");
else
for (int k = 0; k < length; k++) {
// 獲得指定類(lèi)型的注釋
Field_Method_Parameter_Annotation pa = (Field_Method_Parameter_Annotation) parameterAnnotations[j][k];
System.out.print(" " + pa.describe()); // 獲得參數(shù)的描述
System.out.println(" " + pa.type()); // 獲得參數(shù)的類(lèi)型
}
}
System.out.println();
}
}