Class中包含了某个类中的所有信息,比如构造函数、变量域、函数等信息,还可以通过Class类来实例化,在动态加载类中使用较广泛。
首先,设置背景,假设有一个类Person,置于src包中的com.ss包中:
package com.ss;
import java.util.Date;
public class Person{
public Person(){}
public Person(String name, int age){}
protected Person(boolean sex){};
private Person(Date birthday){};
void speak(){
System.out.println("Hello world, I am a person");
}
}
Class<Person> clazz = Person.class;
Person person;
Class<Person> clazz = (Class<Person>) person.getClass(); //此处注意需要进行类型强制转换
通过forName()方法
注意传入的参数,类名应为全称,package之间的包含关系使用.
号进行间隔。
String className = "com.ss.Person";
Class<?> clazz = Class.forName(className);
测试时,可以直接使用Class类的toString方法,打印出class的信息,如:
public static void main(String[] args) {
Person person;
Class<Person> clazz = Person.class;
System.out.println(clazz.toString());
}
输出结果为:
class com.ss.Person
Constructor类专门用来描述构造函数,可以通过它来获取类的构造方法名称、访问权限,还可以通过Constructor来创建类的实例。
首先,假设Person类中有四个不同的构造函数:
public class Person{
public Person(){}
public Person(String name, int age){}
protected Person(boolean sex){};
private Person(Date birthday){};
}
通过指定参数列表获取
只能获取public的构造函数
Class<Person> clazz = Person.class;
Constructor constructor;
constructor = clazz.getConstructor();
constructor = clazz.getConstructor(String.class, int.class);
可以获取所有构造函数
Class<Person> clazz = Person.class;
Constructor constructor;
constructor = clazz.getDeclaredConstructor();
constructor = clazz.getDeclaredConstructor(String.class, int.class);
constructor = clazz.getDeclaredConstructor(boolean.class);
constructor = clazz.getDeclaredConstructor(Date.class);
获取全部构造函数,返回Constructor数组
只能获取public的所有构造函数
Class<Person> clazz = Person.class;
Constructor[] constructors = clazz.getConstructors();
可以获取所有构造函数
Class<Person> clazz = Person.class;
Constructor[] constructors = clazz.getDeclaredConstructors();
与打印Class类的信息相同,只需要用toString方法就可以得到某个类构造函数的信息,如:
public static void main(String[] args) {
Person person;
Class<Person> clazz = Person.class;
Constructor[] constructors = clazz.getDeclaredConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor.toString());
}
}
输出结果为:
private com.ss.Person(java.util.Date)
protected com.ss.Person(boolean)
public com.ss.Person(java.lang.String,int)
public com.ss.Person()
Method类的对象用于描述类的单个方法,可以通过Method类来获取方法的访问权限、参数类型、返回值类型等信息。并且可以通过获取的Method对象来动态执行方法。
首先,设置背景,有一接口Speakable:
public interface Speakable {
public void speak();
public void speak(String message);
}
Person抽象类实现接口Speakable:
public abstract class Person implements Speakable{
private void useTool(){};
private void useTool(String toolName){};
public void eat(String food){};
public final void fly(){};
public native void think();
}
通过参数列表获取
只能获取public的方法
//仅有一个参数时,代表得到参数列表为空的speak方法
Class clazz = Person.class;
Method method = clazz.getMethod("speak");
//两个以上的参数,第一个参数是方法名,后面紧跟参数列表的class
Class clazz = Person.class;
Method method = clazz.getMethod("eat",String.class);
获取所有的方法
Class clazz = Person.class;
Method method = clazz.getDeclaredMethod("useTool");
method = clazz.getDeclaredMethod("useTool", Stirng.class);
获取所有方法,用数组返回
只能获取public的所有函数
Class clazz = Person.class;
Method[] methods = class.getMethods();
获取所有函数方法
Class clazz = Person.class;
Method[] methods = class.getDeclaredMethods();
打印出所有函数方法:
public static void main(String[] args) {
Person person;
Class<Person> clazz = Person.class;
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method.toString());
}
}
输出结果为:
private void com.ss.Person.useTool(java.lang.String)
private void com.ss.Person.useTool()
public void com.ss.Person.eat(java.lang.String)
public final void com.ss.Person.fly()
public native void com.ss.Person.think()
Field类的对象用于描述类的单个字段,可以通过Field对象来获取字段的访问权限、字段类型等信息。并且可以通过获取的Field对象来动态修改字段值。
与Method和Constructor的获取方法基本一致,不再赘述。
//返回一个Field对象,反映此Class对象所表示的类或接口指定的public成员字段
public Field getField(String name);
//返回一个包含Field 对象的数组,这些对象反映此Class对象所表示的类或接口的所有可访问public字段
public Field[] getFields();
//返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段
public FieldgetDeclaredField(Stringname);
//返回一个Field的数组,该数组记录指定类的所有属性的描述对象。如果指定类没有属性,则返回一个空数组
public Field[] getDeclaredFields();
Class类的newInstance()方法
Class<Person> clazz = Person.class;
Person person = (Person) clazz.newInstance(); //需要强制类型转换
Constructor的newInstance()方法
Class<Person> clazz = Person.class;
Constructor constructor = clazz.getConstructor();
Person person;
invoke方法的第一个参数,传入指定的对象(即指定需要执行哪个对象的函数),接下来的参数是执行方法中需要传入的函数参数。
Class<Person> clazz = Person.class;
Person teacher = clazz,=.newInstance();
Method method = clazz.getMethod("speak",String.class);
method.invoke(teacher,"Lesson one!");
Teacher teacher;
Constructor constructor = clazz.getConstructor();
teacher = (Teacher) constructor.newInstance();
Field field = (Field) clazz.getField("teacherName");
field.set(teacher,"Jack");
Field、Method以及Constructor的父类AccessiableObject提供一个方法setAccessiable(boolean flag)
,该方法用于设置访问对象的accessiable标志,该标志为true时,反射的对象在使用时取消java语言访问检查,此时就可以顺利使用反射对象。