JAVA通过反射运行配置文件内容来体现反射的作用
一.直接上项目的构建结构图
1.注意代码和文件全在src\day27\reflectDemo下,如图蓝色选中部分。
2.用着几个简单类来体现用反射调用方法的优点:提高代码的扩展性。
3.首先写几个简单类,Cat,Dog,Person和一个测试类ReflectDemo,此处用class.txt模拟配置文件。
二.补全这几个类的代码
1.Cat.java的代码如下:
提供两个无参无返回值的方法sleep()和eat()
package day27.reflectDemo;
public class Cat {
public void sleep(){
System.out.println("猫睡觉打呼");
}
public void eat(){
System.out.println("猫吃鱼");
}
}
2.Dog.java的代码如下:
同理,提供两个无参无返回值的方法sleep()和eat()
package day27.reflectDemo;
public class Dog {
private void sleep(){
System.out.println("狗睡觉不打呼");
}
public void eat(){
System.out.println("狗吃肉");
}
}
3.Person.java的代码如下:
1)这个类不仅提供了sleep()和eat()两个方法,还提供了两个成员变量,一个公共,一个私有;
2)并且还有一个带参带返回值的且设置为私有的方法private int getAge(int age);
3)这个私有变量和私有方法用来体现反射优点:可以访问私有变量和方法;
4)注意此类中重写了toString()方法。
package day27.reflectDemo;
public class Person {
public String name;
private int age;
public Person() {
}
public String getName() {
return name;
}
private int getAge(int age) {
System.out.println("年龄为:"+age);
return age;
}
public void eat() {
System.out.println("人吃大米");
}
public void sleep() {
System.out.println("人们早睡晚起");
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
4.ReflectDemo.java测试类的代码如下:
1)一般调用方式,就是我们常用的方式:对象调方法
2)反射方式调用方法,运行模拟的配置文件class.txt中的内容
3)此处分别以调用无参无返回值的方法和带参带返回值的方法为例
4)注意:调用方法测试,该类中我注释的两个代码块一和二,根据配置文件中相应的数据来测试,运行时注释掉另一个代码块
package day27.reflectDemo;
import java.io.FileReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Properties;
public class ReflectDemo {
public static void main(String[] args) throws Exception{
// //一般调用方式
// Cat cat = new Cat();
// cat.eat();
// System.out.println("-----------");
//用反射方式来调用
//加载键值对数据
Properties prop = new Properties();
FileReader fr = new FileReader("src\\day27\\reflectDemo\\class.txt");
prop.load(fr);
fr.close();
//获取数据
String className = prop.getProperty("className");
String methodName = prop.getProperty("methodName");
//反射
Class c = Class.forName(className);
Constructor con = c.getConstructor();
Object obj = con.newInstance();
//调用方法测试,以下两段代码分别运行,运行时注释掉另一个代码块,根据配置文件中相应的数据来测试
//调用方法,无参无返回值的方法,这里取名叫代码块一
// Method m1 = c.getMethod(methodName);
// m1.invoke(obj);
// System.out.println("-------");
//调用方法,带参带返回值的方法,这里取名叫代码块二
Method m2 = c.getDeclaredMethod(methodName,int.class); //注意调用带参数方法的不同
m2.setAccessible(true); //访问私有方法将其设置为true
Object objString = m2.invoke(obj,18);
System.out.println("返回值为:" + objString);
}
}
5.看看class.txt的内容怎么写的
1)className是你想要运行的类,这里写的是day27.reflectDemo包下的Person类
2)methodName是你想要运行类中的方法,这里写的是Person类的getAge方法
3)注意:这个文件只是示例,“=” 后边内容根据自己需求来改动即可
className = day27.reflectDemo.Person
methodName = getAge
三.运行程序
1.这里就以下图1的配置来测试运行,即调用Person类的private int getAge(int age)方法,(注意:这里运行测试类的代码块二,注释掉代码块一)其他测试下面继续运行测试
2.修改配置文件内容如下图1,即调用Person类的sleep()方法,这个方法是无参无返回值的,注意修改代码如下图2(即:运行测试类的代码块一,注释掉代码块二),运行结果如图3:
3.修改配置文件内容如下图1,即调用Cat类的eat()方法,这个方法是无参无返回值的,(注意:运行测试类中的代码块一,注释掉代码块二),运行结果如图2:
5.其他测试,可自行测试运行
四.最后,如有错误,谢谢指出,共同学习!