在程序运行期间,每一个对象都属于一个类,同样,所有的类也是Class类的对象。反射就是在程序运行过程中,可以使用 java.lang.reflect 包中的工具获得出类的名称、属性和方法等信息。
现在介绍一下这些用法。
首先,取得类的类型,它是一个Class<?>类型的变量。取得类型的方式有三种:1、类的 class成员;2、Class.forName(String)方法,参数就是类的名字,如果类在包中定义,参数里也要把包名加上;3、通过一个类的其中的一个对象的getClass()获得。
有了Class类型的对象之后,就可以使用Class中的方法来获得一个类的各种信息的了。
- Class类的方法列表中,含有declared的方法,是获得本类的方法或者属性,不含declared的方法,可以获得其父类的公有方法或者属性。获得的属性或者参数,里面都有一个getType()的方法,可以取得对应的类型;获得的方法里面有个getReturnType()的方法,可以获得对应的返回值类型。
- 如果方法中的含有一个字符串参数,那是获得指定名字的方法或者属性。
- 含有field的方法,表示可以取得类的属性。
- 含有method的方法,表示可以取得类的方法。
- 含有construnctor的方法,表示可以取得类的构造器。
- 含有annotation的方法,是用来取得对应的注解的方法。
- 还有其他获得接口和父类的方法。
下面举例说明这些方法的使用。
InterfaceA.java 的源代码
package com.baby;
public interface InterfaceA {
public void dosomething();
public void dosomething(String string);
}
ClassA.java 的源代码
package com.baby;
public class ClassA implements InterfaceA {
public String publicFieldA1;
protected String protectedFieldA2;
private int privateFieldA3;
public ClassA() {
super();
System.out.println("public ClassA()\t" + this);
}
public ClassA(String publicFieldA1, String protectedFieldA2, int privateFieldA3) {
super();
this.publicFieldA1 = publicFieldA1;
this.protectedFieldA2 = protectedFieldA2;
this.privateFieldA3 = privateFieldA3;
System.out.println("public ClassA(String publicFieldA1, String protectedFieldA2, int privateFieldA3)\t" + this);
}
public String getPublicFieldA1() {
return publicFieldA1;
}
public void setPublicFieldA1(String publicFieldA1) {
this.publicFieldA1 = publicFieldA1;
}
public String getProtectedFieldA2() {
return protectedFieldA2;
}
public void setProtectedFieldA2(String protectedFieldA2) {
this.protectedFieldA2 = protectedFieldA2;
}
public int getPrivateFieldA3() {
return privateFieldA3;
}
public void setPrivateFieldA3(int privateFieldA3) {
this.privateFieldA3 = privateFieldA3;
}
@Override
public void dosomething() {
System.out.println("public void dosomething() from ClassA\t" + this);
}
@Override
public void dosomething(String string) {
System.out.println("public void dosomething() from ClassA. string is [" + string + "]\t" + this);
}
}
ClassB.java 的源代码
package com.baby;
public class ClassB extends ClassA implements InterfaceA {
public boolean publicFieldB1;
public int publicFieldB2;
private String privateFieldB3;
protected String protectedFieldB4;
public ClassB() {
super();
System.out.println("public ClassB()\t" + this);
}
public ClassB(String publicFieldA1, String protectedFieldA2, int privateFieldA3) {
super(publicFieldA1, protectedFieldA2, privateFieldA3);
System.out.println("public ClassB(String publicFieldA1, String protectedFieldA2, int privateFieldA3)\t" + this);
}
public ClassB(boolean publicFieldB1, int publicFieldB2, String privateFieldB3, String protectedFieldB4) {
super();
this.publicFieldB1 = publicFieldB1;
this.publicFieldB2 = publicFieldB2;
this.privateFieldB3 = privateFieldB3;
this.protectedFieldB4 = protectedFieldB4;
System.out.println(
"public ClassB(boolean publicFieldB1, int publicFieldB2, String privateFieldB3, String protectedFieldB4)\t"
+ this);
}
public boolean isPublicFieldB1() {
return publicFieldB1;
}
public void setPublicFieldB1(boolean publicFieldB1) {
this.publicFieldB1 = publicFieldB1;
}
public int getPublicFieldB2() {
return publicFieldB2;
}
public void setPublicFieldB2(int publicFieldB2) {
this.publicFieldB2 = publicFieldB2;
}
public String getPrivateFieldB3() {
return privateFieldB3;
}
public void setPrivateFieldB3(String privateFieldB3) {
this.privateFieldB3 = privateFieldB3;
}
public String getProtectedFieldB4() {
return protectedFieldB4;
}
public void setProtectedFieldB4(String protectedFieldB4) {
this.protectedFieldB4 = protectedFieldB4;
}
@Override
public void dosomething() {
System.out.println("public void dosomething() from ClassB\t" + this);
}
@Override
public void dosomething(String string) {
System.out.println("public void dosomething() from ClassB string is [" + string + "]\t" + this);
}
}
ReflectTest.java 主程序的测试代码
package com.baby;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
public class ReflectTest {
/**
* @param args
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
public static void main(String[] args)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
ClassA classA = new ClassA();
classA.dosomething();
ClassB classB = new ClassB();
classB.dosomething();
System.out.println("========获得类类型的方法========");
// 获得类类型的方法1
Class<?> typeOfClassB1 = ClassB.class;
System.out.println("typeOfClassB1\t" + typeOfClassB1);
// 获得类类型的方法2
try {
Class<?> typeOfClassB2 = Class.forName("com.baby.ClassB");
System.out.println("typeOfClassB1\t" + typeOfClassB2);
} catch (ClassNotFoundException e) {
System.out.println("class [com.baby.ClassB] is not found");
}
// 获得类类型的方法3
Class<?> typeOfClassB3 = classB.getClass();
System.out.println("typeOfClassB3\t" + typeOfClassB3);
System.out.println("========获得类的属性1========");
// 获得类的属性。getFields能获得类的非privte的属性
Field[] fields = ClassB.class.getFields();
for (Field field : fields) {
System.out.println("属性的全称名称:" + field.toString());
System.out.println("\t属性的类型:" + field.getType() + "\t属性的名称:" + field.getName() + "\t");
}
System.out.println("========获得类的属性2========");
// 获得类的属性
Field[] declaredFields = ClassB.class.getDeclaredFields();
for (Field field : declaredFields) {
System.out.println("属性的全称名称:" + field.toString());
System.out.println("\t属性的类型:" + field.getType() + "\t属性名称:" + field.getName() + "\t");
}
try {
ClassB.class.getDeclaredField("file1");
} catch (NoSuchFieldException e) {
System.out.println("cat find filed file1");
}
System.out.println("========获得类的方法========");
Method[] methods = ClassB.class.getDeclaredMethods();
for (Method method : methods) {
System.out.println("类的方法:" + method);
System.out.println("\t方法的返回值:" + method.getReturnType() + "\t方法的名称:" + method.getName());
Parameter[] parameters = method.getParameters();
for (Parameter parameter : parameters) {
System.out.println("\t参数类型:" + parameter.getType());
}
}
try {
ClassB.class.getDeclaredMethod("method1");
} catch (NoSuchMethodException e) {
System.out.println("cat find method method1");
}
System.out.println("========获得类的构造器========");
Constructor<?>[] constructors = ClassB.class.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println("类的构造器:" + constructor);
Parameter[] parameters = constructor.getParameters();
for (Parameter parameter : parameters) {
System.out.println("\t参数类型:" + parameter.getType());
}
}
System.out.println("========获得类的接口========");
Class<?>[] classBInterfaces = ClassB.class.getInterfaces();
for (Class<?> itf : classBInterfaces) {
System.out.println("interface from Person is [" + itf.getName() + "] or [" + itf.getSimpleName() + "]");
}
System.out.println("========获得类的父类========");
Class<? super ClassB> classBSuperClasses = ClassB.class.getSuperclass();
System.out.println("super class of Person is [" + classBSuperClasses.getName() + "] or ["
+ classBSuperClasses.getSimpleName() + "]");
//使用invoke来调用对象,即运行对象的一个方法。
System.out.println("========获得调用类的方法========");
try {
Method methodDosomething1 = ClassB.class.getMethod("dosomething");
methodDosomething1.invoke(classB);
} catch (NoSuchMethodException e) {
System.out.println("can not find method dosomething");
}
try {
Method methodDosomething2 = ClassB.class.getMethod("dosomething", String.class);
methodDosomething2.invoke(classB, "test string2");
} catch (NoSuchMethodException e) {
System.out.println("can not find method dosomething(String)");
}
}
}
程序的运行结果:
public ClassA() com.baby.ClassA@139a55
public void dosomething() from ClassA com.baby.ClassA@139a55
public ClassA() com.baby.ClassB@1db9742
public ClassB() com.baby.ClassB@1db9742
public void dosomething() from ClassB com.baby.ClassB@1db9742
========获得类类型的方法========
typeOfClassB1 class com.baby.ClassB
typeOfClassB1 class com.baby.ClassB
typeOfClassB3 class com.baby.ClassB
========获得类的属性1========
属性的全称名称:public boolean com.baby.ClassB.publicFieldB1
属性的类型:boolean 属性的名称:publicFieldB1
属性的全称名称:public int com.baby.ClassB.publicFieldB2
属性的类型:int 属性的名称:publicFieldB2
属性的全称名称:public java.lang.String com.baby.ClassA.publicFieldA1
属性的类型:class java.lang.String 属性的名称:publicFieldA1
========获得类的属性2========
属性的全称名称:public boolean com.baby.ClassB.publicFieldB1
属性的类型:boolean 属性名称:publicFieldB1
属性的全称名称:public int com.baby.ClassB.publicFieldB2
属性的类型:int 属性名称:publicFieldB2
属性的全称名称:private java.lang.String com.baby.ClassB.privateFieldB3
属性的类型:class java.lang.String 属性名称:privateFieldB3
属性的全称名称:protected java.lang.String com.baby.ClassB.protectedFieldB4
属性的类型:class java.lang.String 属性名称:protectedFieldB4
cat find filed file1
========获得类的方法========
类的方法:public void com.baby.ClassB.dosomething()
方法的返回值:void 方法的名称:dosomething
类的方法:public void com.baby.ClassB.dosomething(java.lang.String)
方法的返回值:void 方法的名称:dosomething
参数类型:class java.lang.String
类的方法:public int com.baby.ClassB.getPublicFieldB2()
方法的返回值:int 方法的名称:getPublicFieldB2
类的方法:public boolean com.baby.ClassB.isPublicFieldB1()
方法的返回值:boolean 方法的名称:isPublicFieldB1
类的方法:public void com.baby.ClassB.setPublicFieldB2(int)
方法的返回值:void 方法的名称:setPublicFieldB2
参数类型:int
类的方法:public void com.baby.ClassB.setPublicFieldB1(boolean)
方法的返回值:void 方法的名称:setPublicFieldB1
参数类型:boolean
类的方法:public java.lang.String com.baby.ClassB.getPrivateFieldB3()
方法的返回值:class java.lang.String 方法的名称:getPrivateFieldB3
类的方法:public java.lang.String com.baby.ClassB.getProtectedFieldB4()
方法的返回值:class java.lang.String 方法的名称:getProtectedFieldB4
类的方法:public void com.baby.ClassB.setPrivateFieldB3(java.lang.String)
方法的返回值:void 方法的名称:setPrivateFieldB3
参数类型:class java.lang.String
类的方法:public void com.baby.ClassB.setProtectedFieldB4(java.lang.String)
方法的返回值:void 方法的名称:setProtectedFieldB4
参数类型:class java.lang.String
cat find method method1
========获得类的构造器========
类的构造器:public com.baby.ClassB(boolean,int,java.lang.String,java.lang.String)
参数类型:boolean
参数类型:int
参数类型:class java.lang.String
参数类型:class java.lang.String
类的构造器:public com.baby.ClassB(java.lang.String,java.lang.String,int)
参数类型:class java.lang.String
参数类型:class java.lang.String
参数类型:int
类的构造器:public com.baby.ClassB()
========获得类的接口========
interface from Person is [com.baby.InterfaceA] or [InterfaceA]
========获得类的父类========
super class of Person is [com.baby.ClassA] or [ClassA]
========获得调用类的方法========
public void dosomething() from ClassB com.baby.ClassB@1db9742
public void dosomething() from ClassB string is [test string2] com.baby.ClassB@1db9742
说明:
这个例子里面介绍了一般的用法,没有包含获得并使用注解的介绍。