Java反射机制的几点用法

时间:2021-12-11 05:29:46

什么是Java反射机制?

Java的反射机制是反应Java作为动态(准动态)语言的关键性质。这个机制允许程序在运行时加载、使用编译期间完全未知的classes。具体功能包括:
1、在运行时判断任意一个对象所属的类。
2、在运行时构造任意一个类的对象。
3、在运行时判断任意一个类所具有的成员变量与方法。
4、在运行时调用任意一个对象的方法。
5、在运行时创建新类对象。

定义测试的类

ClassType:

package field;
public class ClassType {
public int pubIntField;
public String pubStringField;
String defStringField;
protected String proStringField;
private String priStringField;

public ClassType(){
prt("default constructor");
}
ClassType(int args1,String args2){
this.pubIntField = args1;
this.pubStringField = args2;
prt("constructor with parameters");
}
public String getPriStringField() {
return priStringField;
}
public void setPriStringField(String priStringField) {
this.priStringField = priStringField;
}
public void prt(String arg){
System.out.println(arg);
}

}

ClassExtendType:

package field;
public class ClassExtendType extends ClassType{
public int pubIntFieldExtend;
public String pubStringFieldExtend;
String defStringFieldExtend;
protected String proStringFieldExtend;
private String priStringFieldExtend;

public ClassExtendType(){
prt("default constructor of extend");
}
ClassExtendType(int args1,String args2){
this.pubIntFieldExtend = args1;
this.pubStringFieldExtend = args2;
prt("constructor with parameters of extend");
}
public String getPriStringFieldExtend() {
return priStringFieldExtend;
}
public void setPriStringFieldExtend(String priStringFieldExtend) {
this.priStringFieldExtend = priStringFieldExtend;
}
public void prt(String arg){
System.out.println(arg);
}
}

在使用Java的反射功能时,基本首先都要获取类的Class对象,再通过Class对象获取其他东西。

获取Class对象

(1)通过getClass()方法

ClassType c = new ClassType();
Class<?> classType = c.getClass();

(2)通过.class

Class<?> classType = ClassType.class;

(3)通过类方法Class.forName()

Class<?> classType = Class.forName("field.ClassType");

获取类的域field

(1)getField()方法
java.lang.Class.getField()返回一个Field对象,它反映此Class对象所表示的类或接口的指定公共成员字段。 name参数是一个字符串,用于指定所需的字段的简单名称。

package field;
import java.lang.reflect.Field;
public class Test {
public static void main(String[]args){
ClassType ct = new ClassType();
Class<?> classType = ct.getClass();
try {
Field field = classType.getField("pubIntField");//在ClassType中存在public int pubIntField域。
System.out.println("field: "+field);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
}
}

输出结果:

default constructor
field:
public int field.ClassType.pubIntField

(2)getFields()方法
java.lang.Class.getFields() 返回一个包含此Class所有public字段的数组,数组长度可为0。

package field;
import java.lang.reflect.Field;
public class Test2 {
public static void main(String[]args){
ClassType ct = new ClassType();
Class<?> classType = ct.getClass();
Field[] field = classType.getFields();
for(Field m:field){//for each
System.out.println(m);
}
}
}

输出结果:

default constructor
public int field.ClassType.pubIntField
public java.lang.String field.ClassType.pubStringField

(3)getDeclaredField()方法与getDeclaredFields()方法
这两个方法用法与前面基本类似但返回值不限定public字段

获取类的方法method

(1)getMethods()方法

package field;
import java.lang.reflect.Method;
public class Test3 {
public static void main(String[] args) {
ClassExtendType cet = new ClassExtendType();
Class<?> c = cet.getClass();
Method[] method = c.getMethods();
for(Method m:method){
System.out.println(m);
}
}
}

输出结果:

default constructor
default constructor of extend
public void field.ClassExtendType.prt(java.lang.String)
public java.lang.String field.ClassExtendType.getPriStringFieldExtend()
public void field.ClassExtendType.setPriStringFieldExtend(java.lang.String)
public java.lang.String field.ClassType.getPriStringField()
public void field.ClassType.setPriStringField(java.lang.String)
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()

(2)getDeclaredMethods()方法
运行结果:

default constructor
default constructor of extend
public void field.ClassExtendType.prt(java.lang.String)
public java.lang.String field.ClassExtendType.getPriStringFieldExtend()
public void field.ClassExtendType.setPriStringFieldExtend(java.lang.String)

获取类的构造器constructor

(1)使用getConstructor()获取构造器

Constructor<?> constructors = c.getDeclaredConstructor(int.class,String.class);

(2)使用getConstructors()获取构造器

Constructor<?>[] constructors = classType.getConstructors();  
for (Constructor<?> m : constructors)
{
System.out.println(m);
}

新建类的实例newInstance()

(1)调用无参的
使用class对象的newInstance()方法:

public class Test3 {
public static void main(String[] args) {
ClassExtendType cet = new ClassExtendType();
Class<?> c = cet.getClass();
try {
Object cet2 = c.newInstance();
System.out.println(cet2);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}

输出结果:

default constructor
default constructor of extend
default constructor
default constructor of extend
field.ClassExtendType@12504e0

使用constructor的newInstance()方法:

Class<?> classType = ClassExtendType.class;
Constructor<?> c = classType.getConstructor();
Object inst = c.newInstance();

(2)调用有参的
调用带参数Constructor对象的newInstance方法

Constructor<?> c2 =
classType.getDeclaredConstructor(int.class, String.class);
Object inst = c2.newInstance(1, "123");