本文主要介绍了Java反射机制的原理和用法,并结合实例详细分析了Java反射机制的相关概念、原理、基本使用方法和操作注意事项。有需要的可以参考一下。
本文结合实例介绍了Java反射机制的原理和用法。分享给你,供你参考,如下:
反思,程序员的幸福!
1、什么是反射?
Java反射意味着你可以知道任何一个类在运行状态下的所有属性和方法。对于任何对象,都可以调用它的任何方法和属性;并且可以改变它的属性。而这也是Java被视为动态(或准动态,为什么是准动态?一般来说,动态语言的定义是程序运行时程序结构或变量类型可以改变。这种语言叫做动态语言。从这个角度来说,Perl、Python、Ruby都是动态语言,而C、Java、C#都不是动态语言。)语言的一个关键属性。
2、反射能做什么?
我们知道,反射机制允许程序在运行时获得任何已知名称的类的内部信息,包括其修饰符、字段、方法等。并且可以在运行时更改字段的内容或调用方法。那么我们就可以更加灵活地编写代码,代码可以在运行时进行组装,这样就不需要在组件之间链接源代码,降低了代码的耦合度;还有动态代理的实现等。但需要注意的是,反射使用不当会造成资源消耗高!
3、反射的具体实现
下面是一个基础类人。
包com ys . reflex;
公共类人员{
//私有属性
私有字符串名称=' Tom
//公共属性
public int age=18
//构造方法
公共人物(){
}
//私有方法
私有void say(){
System.out.println('private say(). ');
}
//公共方法
公共无效工作(){
System.out.println('public work(). ');
}
}
上课的三种方式
//1.通过对象调用getClass()方法来获取,这通常用在:例如,如果发送一个对象。
//对象的类型,也不知道你到底是什么类。这样
人员p1=新人员();
class C1=P1 . getclass();
//2.直接通过类名获取。班级。这种方法最安全可靠,程序性能更高。
//这表明任何类都有一个隐式静态成员变量类
c2类=Person.class
//3.通过使用最多的类对象的forName()的静态方法获取,
//但是可能会引发ClassNotFoundException异常
class C3=class . forname(' com . ys . reflex . person ');
需要注意的是,在JVM中一个类只能有一个类实例,也就是我们用equals比较上面得到的C1、C2、C3,发现都是真的。
获取成员变量、成员方法、接口、超类、构造方法等。通过阶级阶级。
查找API,可以看到Class有很多方法:
GetName():获取类的全名。
GetFields():获取类的公共类型属性。
GetDeclaredFields():获取类的所有属性。包括私有声明和继承的类。
GetMethods():获取类的公共类型的方法。
GetDeclaredMethods():获取该类的所有方法。包括私有声明和继承的类。
Get (string name,class [] parameterTypes):获取类的具体方法,name参数指定方法的名称,parameterTypes参数指定方法的参数类型。
GetConstructors():获取类的公共类型的构造函数。
get constructor(class[]parameterTypes):获取类的具体构造函数,parameter types参数指定构造函数的参数类型。
NewInstance():通过它的无参数构造函数创建这个类的对象。
让我们通过一个例子来综合演示以上方法:
//获取类的全名
string class name=C2 . getname();
system . out . println(class name);//output com.ys.reflex.Person
//获取该类的公共类型的属性。
field[]fields=C2 . get fields();
for(字段字段:字段){
system . out . println(field . getname());//年龄
}
//获取该类的所有属性。包括私人的。
field[]所有字段=C2。getdeclaredfields();
for(Field field : allFields){
系统。出去。println(字段。getname());//姓名年龄
}
//获得类的公众的类型的方法。这里包括目标类的一些方法
方法[]方法=C2。get方法();
对于(方法方法:方法){
系统。出去。println(方法。getname());//工作waid equls toString hashCode等
}
//获得类的所有方法。
方法[]所有方法=C2。getdeclaredmethods();
for(Method method : allMethods){
系统。出去。println(方法。getname());//工作说
}
//获得指定的属性
字段f1=C2。getfield(“年龄”);
系统。出去。println(f1);
//获得指定的私有属性
字段F2=C2。getdeclaredfield(' name ');
//启用和禁用访问安全检查的开关,值为没错,则表示反射的对象在使用时应该取消Java 语言(一种计算机语言,尤用于创建网站)语言(一种计算机语言,尤用于创建网站)语言的访问检查;反之不取消
F2。设置可访问性(true);
系统。出去。println(F2);
//创建这个类的一个对象
对象p2=C2。新实例();
//将p2对象的第二子代属性赋值为鲍勃,f2属性即为私有属性名字
f2.set(p2,' Bob ');
//使用反射机制可以打破封装性,导致了Java 语言(一种计算机语言,尤用于创建网站)语言(一种计算机语言,尤用于创建网站)对象的属性不安全。
系统。出去。println(F2。get(p2));//鲍勃
//获取构造方法
构造函数[]构造函数=C2。获取构造函数();
对于(构造函数构造函数:构造函数){
系统。出去。println(构造函数。tostring());//public com.ys.reflex.Person()
}
4、根据反射获取父类属性
父类Parent.java
公共类父级{
公共字符串public field=' parent _ public field ';
受保护的字符串protect field=' parent _ protect field ';
字符串默认字段=' parent _ default field
私有字符串私有字段=' parent _ private field
}
子类Son.java
公共类子扩展父{
}
公共类反射测试{
@测试
public void testGetParentField()引发异常{
C1等级=等级。forname(' com。ys。模型。子’);
//获取父类私有属性值
系统。出去。println(获取字段值(C1。new instance(),' private field '));
}
公共静态字段getDeclaredField(对象对象,字符串字段名){
字段字段=空
c类=obj。getclass();
for(;c!=object . clasc=c . get super class()){
尝试{
field=c . getdeclaredfield(字段名);
字段。设置可访问性(true);
返回字段;
}catch(异常e){
//这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。
//如果这里的异常打印或者往外抛,则就不会执行c=c.getSuperclass(),最后就不会进入到父类中了
}
}
返回空
}
公共静态对象getFieldValue(Object对象,字符串字段名)引发异常{
field field=getDeclaredField(对象,字段名);
返回字段。get(对象);
}
}
通过执行上述代码,我们获得了父类的私有属性值,这里要注意的是直接通过反射获取子类的对象是不能得到父类的属性值的,必须根据反射获得的子类班级对象在调用getSuperclass()方法获取父类对象,然后在通过父类对象去获取父类的属性值。
5、反射总结
灵活使用反射能让我们代码更加灵活,这里比如JDBC原生代码注册驱动,休眠的实体类,春天的面向切面编程等等都有反射的实现。但是凡事都有两面性,反射也会消耗系统的性能,增加复杂性等,合理使用才是真!
更多Java 语言(一种计算机语言,尤用于创建网站)语言(一种计算机语言,尤用于创建网站)相关内容感兴趣的读者可查看本站专题: 《Java面向对象程序设计入门与进阶教程》 、 《Java数据结构与算法教程》 、 《Java操作DOM节点技巧总结》 、 《Java文件与目录操作技巧汇总》 和《Java缓存操作技巧汇总》
希望本文所述对大家Java 语言(一种计算机语言,尤用于创建网站)语言(一种计算机语言,尤用于创建网站)程序设计有所帮助。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。