反射的简单总结
反射:通过Object的Class类对象,获取对象所属类的相关信息,从而实现对类的各种操作。
一、获取Class对象的方法
1.Class.forName(全限定类名)
全限定类名=包名+类名 这里不要写错,否则会报ClassNotFoundException
如:com.company.day23_reflect.Student
Class personCls = Class.forName("com.company.reflectdemo.demo1.Person");
2.类名.class
Class personCls2 = Person.class;
3.对象.getClass()
Person person = new Person();
Class personCls3 = person.getClass();
二、反射的使用
反射常常会和配置文件一起使用,这里简单讲一下Properties类的使用。
成员方法
返回值 | 方法 | 说明 |
---|---|---|
void | load(InputStream inStream) | 从输入流中读取属性列表(键值对)。 |
void | load(Reader reader) | 按简单的面向行的格式从输入字符流中读取属性列表(键值对)。 |
String | getProperty(String key) | 用指定的键在此属性列表中搜索属性。 |
// 创建Properties对象
Properties properties = new Properties();
//加载properties配置文件,有两种加载方法,一般没有中文的使用第一种参数为InputStream类型的load方法。
//若配置文件中有非ASCII字符,如中文则需要使用第二种Reader类型参数的load方法,可以指定读取的字符集
properties.load(new InputStreamReader(new FileInputStream("dict.properties"),"gbk"));
通过Class类对象主要可以获取三个方面的信息
1.构造方法
方法 | 作用 |
---|---|
getConstructor(Class<?>… parameterTypes) | 获取一个公有构造方法对象 |
getConstructors() | 获取所有公有构造方法对象 |
getDeclaredConstructor(Class<?>… parameterTypes) | 获取一个构造方法对象 |
getDeclaredConstructors() | 获取所有构造方法对象 |
2.成员变量
方法 | 作用 |
---|---|
getField(String name) | 获取一个公有成员变量对象 |
getFields() | 获取所有公有成员变量对象 |
getDeclaredField(String name) | 获取一个成员变量对象(包括私有) |
getDeclaredFields() | 获取所有成员变量对象(包括私有) |
3.成员方法
方法 | 作用 |
---|---|
getMethod(String methodName, Class<?>… parameterTypes) | 获取一个公有方法 |
getMethods() | 获取所有公有方法 |
getDeclaredMethod(String methodName, Class<?>… parameterTypes) | 获取一个方法 |
getDeclaredMethod() | 获取所有方法 |
解除private权限限制的方法 setAccessable(true)
简单小结
- get类型,获取一个公有类型对象
- gets类型,获取所有公有类型对象
- getDeclared类型,获取一个类型对象(可以是私有)
- getDeclareds类型,获取所有类型对象(包括私有)
简单使用:通过读取配置文件执行对象的方法
//配置文件
className=com.company.day23_reflect.Student
methodName=doSomething
public class Work2 {
/**
*此方法通过读取配置文件内容,新建对象实例,从而执行对象的普通无参方法
* @param configFilePath 表示配置文件路径
*/
public void callTargetMethod(String configFilePath) throws Exception {
Properties properties = new Properties();
properties.load(new FileInputStream(configFilePath));
//获取方法名和对象名,配置文件里的类名需要写全限定类名
String className = properties.getProperty("className");
String methodName = properties.getProperty("methodName");
//获取Class类对象、默认无参构造方法、指定普通无参方法(方法最好设置成可访问)
Class clazz = Class.forName(className);
Constructor constructor = clazz.getConstructor();
Method method = clazz.getMethod(methodName);
method.setAccessible(true);
Object o = constructor.newInstance();
method.invoke(o);
}
}
//测试类
//尽量写相对路径,减少麻烦
public class Test2 {
public static void main(String[] args) throws Exception{
new Work2().callTargetMethod("src\\com\\company\\reflectdemo\\dict.properties");
}
}