java 反射 参数列表配置化,Java反射机制在Spring IOC中的应用

参考结合网上博客做个笔记

反射的定义:

反射是java语言的一个特性,它允许程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作。例如它允许一个java的类获取它所有的成员变量和方法并且显示出来。

反射机制的优点与缺点:

首先要搞清楚为什么要用反射机制?直接创建对象不就可以了吗,这就涉及到了动态与静态的概念。

==静态编译==:在编译时确定类型,绑定对象,即通过。

==动态编译==:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,有以降低类之间的藕合性。

==反射机制的优点==:可以实现动态创建对象和编译,体现出很大的灵活性(特别是在J2EE的开发中它的灵活性就表现的十分明显)。通过反射机制我们可以获得类的各种内容,进行了反编译。对于JAVA这种先编译再运行的语言来说,反射机制可以使代码更加灵活,更加容易实现面向对象。

比如,一个大型的软件,不可能一次就把把它设计的很完美,当这个程序编译后,发布了,当发现需要更新某些功能时,我们不可能要用户把以前的卸载,再重新安装新的版本,假如这样的话,这个软件肯定是没有多少人用的。采用静态的话,需要把整个程序重新编译一次才可以实现功能的更新,而采用反射机制的话,它就可以不用卸载,只需要在运行时才动态的创建和编译,就可以实现该功能。

==反射机制的缺点==:对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于只直接执行相同的操作。

Java反射使用

1)、forName

public static Class> forName(String className) throws ClassNotFoundException

相当于:Class.forName(className, true, currentLoader)

参数 :

className - 所需类的完全限定名称。

Class c = Class.forName("com.ash.demo.Test")

//结果

class com.ash.demo.Test

2)、.class

Class c2 = String.class;

//结果

class java.lang.String

--

public class Test {

public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {

//获取对象

Class> student = Class.forName("com.test.Student");

//创建实例

Student student1 = (Student) student.newInstance();

//通过反射获取对象的属性、方法

student1.setAge(18);

student1.setName("zs");

student1.setClassName("移动应用开发");

System.out.println(student1);

}

}

//结果

Student{name='zs', age=18, className='移动应用开发'}

常用方法:

getDeclaredMethods() 获取所有的方法(包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法)

getReturnType() 获得方法的返回类型

getParameterTypes() 获得方法的传入参数类型

getDeclaredMethod(String name, Class>... parameterTypes) 获得特定的方法

3)、getMethod

public Method getMethod(String name, Class>... parameterTypes)

参数 :

name - 方法的名称

parameterTypes - 参数列表

结果 :

方法对象匹配指定的 name和 parameterTypes

4)、invoke

public abstract Object invoke(Class m, Object... args)

参数 :

m - 在服务上调用的方法

args - 方法参数

--

public class Test {

public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {

try {

//反射类

Class demoClass = Demo02.class;

//获取类的方法

Method cs = demoClass.getMethod("cs", String.class);

//调用方法

cs.invoke(demoClass.newInstance(),"zs");

} catch (NoSuchMethodException | InvocationTargetException e) {

e.printStackTrace();

}

}

}

class Demo02 {

public void cs(String name) {

System.out.println("----" + name + "----");

}

}

Spring通过配置进行实例化对象,并放到容器中的伪代码:

//解析元素的id属性得到该字符串值为“studentDao”

String idStr = "studentDao";

//解析元素的class属性得到该字符串值为“"com.ash.demo.service.StudentDaoImpl”

String classStr = ""com.ash.demo.service.StudentDaoImpl";

//利用反射知识,通过classStr获取Class类对象

Class> cls = Class.forName(classStr);

//实例化对象

Object obj = cls.newInstance();

//container表示Spring容器

container.put(idStr, obj);

当一个类里面需要应用另一类的对象时

//解析元素的name属性得到该字符串值为“studentDao”

String nameStr = "studentDao";

//解析元素的ref属性得到该字符串值为“studentDao”

String refStr = "studentDao";

//生成将要调用setter方法名 , substring(开始取值,结束(不取值)),toUpperCase转换为大写

String setterName = "set" + nameStr.substring(0, 1).toUpperCase()

+ nameStr.substring(1);

//获取spring容器中名为refStr的Bean,该Bean将会作为传入参数

Object paramBean = container.get(refStr);

//获取setter方法的Method类,此处的cls是刚才反射代码得到的Class对象

Method setter = cls.getMethod(setterName, paramBean.getClass());

//调用invoke()方法,此处的obj是刚才反射代码得到的Object对象

setter.invoke(obj, paramBean);

只要在代码或配置文件中看到类的完整路径(包.类),其底层原理基本上使用的就是Java的反射机制。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值