public class Student {
private String name;
private int age;
private String gender;
public Student() {
}
public Student(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
}
- 读取配置文件信息:创建Properties集合将配置文件信息放入集合中。
- 创建字节输入流对象并关联源文件。
- 下载文件。
- 关闭流。
import java.io.FileInputStream;
import java.util.Properties;
public class ReflectDemo01 {
public static void main(String[] args)throws Exception{
//创建Properties集合
Properties info = new Properties();
//创建字节输入流对象并关联源文件
FileInputStream fis = new FileInputStream("src/stu.properties");
//下载文件
info.load(fis);
//关闭流
fis.close();
System.out.println(info);
}
}
- 我们想创建一个学生对象,不要直接去new它,因为在配置文件中有一个class对应一个类全名,我们根据class获得一个类全名字符串就可以得到一个class对象,则可以创建学生对象了。
- 不过此时得到的name,age,gender都是默认值,接下来就需要利用反射机制对他们赋值。
import java.io.FileInputStream;
import java.util.Properties;
public class ReflectDemo01 {
public static void main(String[] args)throws Exception{
//创建Properties集合
Properties info = new Properties();
//创建字节输入流对象并关联源文件
FileInputStream fis = new FileInputStream("src/stu.properties");
//加载数据到集合中
info.load(fis);
//关闭流
fis.close();
//根据Class获得类全名字符串
String str = info.getProperty("class");
//根据类全名获得Class对象
Class c = Student.class;
//创建学生对象
Object obj = c.newInstance();
System.out.println(info);
System.out.println(obj);
}
}
- 利用反射获得类所有的成员变量,遍历所有的成员变量。
- 三个成员变量的名字相当于键,只需要获得成员变量的名字就可以给成员变量赋值了。
- 获得成员变量名称,即Properties集合的键,根据键获得值就可以给对应的field赋值。
- 给对象obj的成员变量赋值。
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.util.Properties;
public class ReflectDemo01 {
public static void main(String[] args)throws Exception{
//创建Properties集合
Properties info = new Properties();
//创建字节输入流对象并关联源文件
FileInputStream fis = new FileInputStream("src/stu.properties");
//加载数据到集合中
info.load(fis);
//关闭流
fis.close();
//根据Class获得类全名字符串
String str = info.getProperty("class");
//根据类全名获得Class对象
Class c = Student.class;
//创建学生对象
Object obj = c.newInstance();
System.out.println(info);
//获得类的所有成员变量
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
//获得成员变量名称
String name = field.getName();
//根据成员变量获得对应的值
String value = info.getProperty(name);
System.out.println("name="+name+",value="+value);
//暴力反射
field.setAccessible(true);
//判断成员变量的类型
Class type = field.getType();
if(type == int.class){
field.setInt(obj,Integer.parseInt(value));
}else {
//给对象obj的成员变量赋值
field.set(obj,value);
}
}
System.out.println(obj);
}
}
扩展:根据不同的配置文件产生不同的对象(利用泛型)(模仿Spring框架)
假设还有一个Book文件的配置信息
public class Book {
private String name;
private double price;
private String author;
public Book() {
}
public Book(String name, double price, String author) {
this.name = name;
this.price = price;
this.author = author;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", price=" + price +
", author='" + author + '\'' +
'}';
}
}
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.util.Properties;
public class ReflectDemo01 {
public static void main(String[] args)throws Exception{
Student stu = creatObject("src/stu.properties");
Book book = creatObject("src/book.properties");
System.out.println(book);
System.out.println(stu);
}
public static T creatObject(String file)throws Exception{
//创建Properties集合
Properties info = new Properties();
//创建字节输入流对象并关联源文件
FileInputStream fis = new FileInputStream(file);
//加载数据到集合中
info.load(fis);
//关闭流
fis.close();
//根据Class获得类全名字符串
String str = info.getProperty("class");
//根据类全名获得Class对象
Class c = Class.forName(str);
//创建对象
Object obj = c.newInstance();
//System.out.println(info);
//获得类的所有成员变量
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
//获得成员变量名称
String name = field.getName();
//根据成员变量获得对应的值
String value = info.getProperty(name);
System.out.println("name="+name+",value="+value);
//暴力反射
field.setAccessible(true);
//判断成员变量的类型
Class type = field.getType();
if(type == int.class){
field.setInt(obj,Integer.parseInt(value));
}else if(type == double.class){
field.setDouble(obj,Double.parseDouble(value));
}else {
//给对象obj的成员变量赋值
field.set(obj,value);
}
}
return (T)obj;
}
}
- java.lang.ClassNotFoundException: sunny.reflect.Student :运行发现报错了,这是因为stu.properties和book.properties两个配置文件里面的信息不小心出现了空格,那么在创建对象的时候是加了空格的,这样就找不到对象对应的类,出现报错的情况,为了防止这种情况的发生,我们可以在获得类全名字符串的时候加上trim方法,消除前后的空格。
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.util.Properties;
public class ReflectDemo01 {
public static void main(String[] args)throws Exception{
Student stu = creatObject("src/stu.properties");
Book book = creatObject("src/book.properties");
System.out.println(book);
System.out.println(stu);
}
public static T creatObject(String file)throws Exception{
//创建Properties集合
Properties info = new Properties();
//创建字节输入流对象并关联源文件
FileInputStream fis = new FileInputStream(file);
//加载数据到集合中
info.load(fis);
//关闭流
fis.close();
//根据Class获得类全名字符串
String str = info.getProperty("class").trim();
//根据类全名获得Class对象
Class c = Class.forName(str);
//创建对象
Object obj = c.newInstance();
//System.out.println(info);
//获得类的所有成员变量
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
//获得成员变量名称
String name = field.getName();
//根据成员变量获得对应的值
String value = info.getProperty(name);
System.out.println("name="+name+",value="+value);
//暴力反射
field.setAccessible(true);
//判断成员变量的类型
Class type = field.getType();
if(type == int.class){
field.setInt(obj,Integer.parseInt(value));
}else if(type == double.class){
field.setDouble(obj,Double.parseDouble(value));
}else {
//给对象obj的成员变量赋值
field.set(obj,value);
}
}
return (T)obj;
}
}