分享以一下最近学习java的网站是:https://how2j.cn/k/reflection/reflection-usage/1111.html?p=131627
这篇文章也是根据网站的来学习。
一、关于反射机制
1.先要了解的概念
1.1.类对象概念
所有的类,都存在一个类对象,这个类对象用于提供类本身的信息,比如有几种构造方法, 有多少属性,有哪些普通方法。
类:有定义好的属性、方法的,可以完成一定功能的class
对象:类实例化,就是给类中的属性赋值,在内存中开辟一个这个类的实际的存在;
类对象:用来描述这种类,都有什么属性,什么方法的(不关对象的事情,不是实例化的)
1.2如何获取类对象
有三种,比如Hero是我们创建好的一个类
Class.forName(“package.Hero”)
Hero.class
New Hero.getClass()
2.反射机制
2.1 使用反射机制获取对象
与传统的通过new 来获取对象的方式不同
反射机制,会先拿到Hero的“类对象”,然后通过类对象获取“构造器对象”
再通过构造器对象创建一个对象
package reflection;
import java.lang.reflect.Constructor;
import charactor.Hero;
public class TestReflection {
public static void main(String[] args) {
//传统的使用new的方式创建对象
Hero h1 =new Hero();
h1.name = "teemo";
System.out.println(h1);
try {
//使用反射的方式创建对象
String className = "charactor.Hero";
//类对象
Class pClass=Class.forName(className);
//构造器
Constructor c= pClass.getConstructor();
//通过构造器实例化
Hero h2= (Hero) c.newInstance();
h2.name="gareen";
System.out.println(h2);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2.2反射有什么用
反射非常强大,但是学习了之后,会不知道该如何使用,反而觉得还不如直接调用方法来的直接和方便。
通常来说,需要在学习了Spring 的依赖注入,反转控制之后,才会对反射有更好的理解,但是刚学到这里的同学,不一定接触了Spring,所以在这里举两个例子,来演示一下反射的一种实际运用。
2.2.1业务类
首先准备两个业务类,这两个业务类很简单,就是各自都有一个业务方法,分别打印不同的字符串
Service1.java
package reflection;
public class Service1 {
public void doService1() {
System.out.println("正在使用业务方法1完成业务1");
}
}
Service2.java
package reflection;
public class Service2 {
public void doService2() {
System.out.println("正在使用业务方法2完成业务2");
}
}
2.2.2非反射方式
当需要从第一个业务方法切换到第二个业务方法的时候,使用非反射方式,必须修改代码,并且重新编译运行,才可以达到效果
Test.java
package reflection;
public class Test {
public static void main(String[] args) {
new Service1().doService1();
}
}
切换业务时修改代码:
Test.java
package reflection;
public class Test {
public static void main(String[] args) {
// new Service1().doService1();
new Service2().doService2();
}
}
2.2.3反射方式
使用反射方式,首先准备一个配置文件,就叫做spring.txt吧, 放在src目录下。 里面存放的是类的名称,和要调用的方法名。
在测试类Test中,首先取出类名称和方法名,然后通过反射去调用这个方法。
当需要从调用第一个业务方法,切换到调用第二个业务方法的时候,不需要修改一行代码,也不需要重新编译,只需要修改配置文件spring.txt,再运行即可。
这也是Spring框架的最基本的原理,只是它做的更丰富,安全,健壮。
2.2.3.1当使用业务方法1时
SpringTest.java
package reflection;
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Properties;
public class SpringTest {
@SuppressWarnings({"rawtypes","unchecked"})//告诉编译器忽略指定的警告,不用在编译完成后出现警告信息
public static void main(String[] args) throws Exception {
//从spring.txt中获取类名称和方法名称
File springConfigFile=new File("D:\\java\\eclipse\\eclipse-workspace\\j2se\\src\\spring.txt");
Properties springConfig=new Properties();
springConfig.load(new FileInputStream(springConfigFile));
String className = (String)springConfig.get("class");
String methodName = (String)springConfig.get("method");
//根据类名获取类对象
Class clazz =Class.forName(className);
//根据方法名称,获取方法对象
Method m = clazz.getMethod(methodName);
//获取构造器
Constructor c = clazz.getConstructor();
//根据构造器,实例化出对象
Object service = c.newInstance();
//调用对象的指定方法
m.invoke(service);
}
}
运行结果:
2.2.3.2切换到业务2时
只需要修改spring.txt中的内容
而不用修改SpringTest.java中的代码
运行结果:
来源:CSDN
作者:画船听雨眠_zj
链接:https://blog.csdn.net/qq_42246380/article/details/104560432