Java编程反射机制用法入门与实例总结
本文实例讲述了Java编程反射机制用法。分享给大家供大家参考,具体如下:
前言:反射:动态获取类(字节码文件如本篇中的Person.class),并对其成员进行运行。反射在Android应用层的开发中可能遇到会稍微少一点,但对于想打通底层的小伙伴来说,必须要熟练掌握运用。
实体类
Person.java
packagecom.sunwenou.reflect;//包名
publicclassPerson{
privateStringname;
privateintage;
publicPerson(){//无参
}
publicPerson(Stringname,intage){//带参
super();
this.name=name;
this.age=age;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicintgetAge(){
returnage;
}
publicvoidsetAge(intage){
this.age=age;
}
@Override
publicStringtoString(){
returnname+","+age;
}
publicvoidshow(){//空参
System.out.println("show");
}
publicvoidfun(Stringss){//带参
System.out.println(ss);
}
publicstaticvoidfunction(){//静态
System.out.println("static");
}
}
动态获取字节码文件的方法
本篇中为使博文看起来简洁,一概抛出Exception,并省略import,下同。
packagecom.sunwenou.reflect;
publicclassDemo1{
/**
*动态获取字节码文件的方法
*1:使用Object类提供的ClassgetClass()方法
*这种方法需要对象
*2:每种数据类型都有一个静态的class属性,这个属性返回的这种数据类型所属字节码文件对象
*int.classPerson.class
*3:使用Class提供的forName()方法
*只需要提供一个字符串,这个字符串由包名+类名构成
*/
publicstaticvoidmain(String[]args)throwsException{
//getClaz();
//getCalz2();
getClaz3();
}
//使用Class提供的forName()方法
publicstaticvoidgetClaz3()throwsException{
Class>claz=Class.forName("com.sunwenou.reflect.Person");
Class>claz2=Class.forName("com.sunwenou.reflect.Person");
System.out.println(claz==claz2);
}
//每种数据类型都有一个静态的class属性
publicstaticvoidgetCalz2(){
Classp1=Person.class;
Classp2=Person.class;
System.out.println(p1==p2);
}
//使用Object类提供的ClassgetClass()方法
publicstaticvoidgetClaz(){
Personperson1=newPerson();
Classclaz=person1.getClass();//Person.class
Personperson2=newPerson();
Classclaz2=person2.getClass();//Person.class
System.out.println(claz==claz2);
}
}
动态获取类,并创建对象
packagecom.sunwenou.reflect;
publicclassDemo2{
publicstaticvoidmain(String[]args)throwsException{
//createObj();
createObj2();
}
publicstaticvoidcreateObj2()throwsException{
//Personperson=newPerson("lisi",23);
//得到字节码文件对象
Class>claz=Class.forName("com.sunwenou.reflect.Person");//Person.class
//得到带参数的构造方法所属的Constructor类型的对象
Constructorconstructor=claz.getConstructor(String.class,int.class);
//使用Constructor类提供的创建对象的方法创建对象
Personperson=(Person)constructor.newInstance("lisi",23);
System.out.println(person);
}
publicstaticvoidcreateObj()throwsException{
//Personperson=newPerson();
//得到字节码文件对象
Class>claz=Class.forName("com.sunwenou.reflect.Person");
Objectobj=claz.newInstance();//默认使用空参的构造方法创建对象
System.out.println(obj);
}
}
动态获取类并为成员变量赋值
packagecom.sunwenou.reflect;
publicclassDemo3{
publicstaticvoidmain(String[]args)throwsException{
//Personp=newPerson();
//p.name="lisi";
//得到字节码文件对象
Class>claz=Class.forName("com.sunwenou.reflect.Person");
//得到成员变量所属的Field类型的对象
//Fieldfield=claz.getField("name");//得到的是public权限的成员
Fieldfield=claz.getDeclaredField("name");//得到所有声明的字段
System.out.println(field);
//非静态成员变量是依赖于对象的
Objectobj=claz.newInstance();
field.setAccessible(true);//暴力破解,设置为可访问的
field.set(obj,"张三");
System.out.println(obj);
}
}
动态获取类,并执行方法
packagecom.sunwenou.reflect;
publicclassDemo4{
publicstaticvoidmain(String[]args)throwsException{
//method1();
method2();
method3();
}
publicstaticvoidmethod3()throwsException{
//得到字节码文件对象
Class>claz=Class.forName("com.sunwenou.reflect.Person");
Methodm=claz.getMethod("function",null);
m.invoke(null,null);
}
////执行带参数的方法
publicstaticvoidmethod2()throwsException{
//得到字节码文件对象
Class>claz=Class.forName("com.sunwenou.reflect.Person");
Methodm=claz.getMethod("fun",String.class);
Objectobj=claz.newInstance();
m.invoke(obj,"hello");
}
//执行无参的方法
publicstaticvoidmethod1()throwsException{
//Personperson=newPerson();person.show();
//得到字节码文件对象
Class>claz=Class.forName("com.sunwenou.reflect.Person");
//得到被执行的方法所属的字节码文件对象
Methodm=claz.getMethod("show",null);
//非静态方法是依赖于对象的
Objectobj=claz.newInstance();
//执行方法
m.invoke(obj,null);
}
}
这就是反射的基本用法,我们就可以在不能通过正常创建对象的时候通过对象的字节码文件来创建对象,并执行其中的方法,你学会了吗??
更多关于java相关内容感兴趣的读者可查看本站专题:《Java面向对象程序设计入门与进阶教程》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》
希望本文所述对大家java程序设计有所帮助。