Java如何基于反射机制获取不同的类
什么是反射机制
Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键(在运行阶段可以改变其结构)
特点:
1、极大的提高了程序的灵活性和扩展性,降低模块的耦合性,提高自身的适应能力
2、通过反射机制可以让程序创建和控制任何类的对象,无需提前硬编码目标类
3、能够在运行时构造一个类的对象、判断一个类所具有的成员变量和方法、调用一个对象的方法(包括private),可能会有安全隐患
4、是构建框架技术的基础所在,使用反射可以避免将代码写死在框架中
5、包含动态类型,而JVM不能对动态代码优化,所以效率会比较低
在Java中可以通过ReflectionAPIs在运行时动态生成class实体,通过Constructor创建类实例、Field访问成员属性、Method调用方法
Class类
在Java中,每个class都有一个相应的Class对象。在编译完成后,在生成的.class文件中,会产生一个Class对象,用于表示这个类的类型信息。
特点:
1、由系统创建Class类
2、同一个类的实例指向同一个Class对象
3、通过Class可以完整的得到一个类所有被加载的结构
4、Class类是Java反射的基础
获得Class类的方法:
publicclassMyReflect{
publicstaticvoidmain(String[]args)throwsClassNotFoundException{
Teachert=newTeacher();
//1、通过对象获得
Classc1=t.getClass();
//2、forName+全限定名获得
Classc2=Class.forName("reflect.Teacher");
//3、通过类名获得
Classc3=Teacher.class;
//4、基本数据类型的Type属性获得
Classc4=Double.TYPE;
//5、通过子类的Class对象获得
Classc5=c1.getSuperclass();
}
}
classPerson{
Stringname;
publicPerson(){
}
}
classTeacherextendsPerson{
publicTeacher(){
}
}
getXXX为获取public构造器、属性、方法
getDeclaredXXX获取任意构造器、属性、方法(包括private)
setAccessible方法避开权限检测,用以访问权限不足的成员
以下不在赘述
准备:Person类以及Tercher子类
packagereflect;
classPerson{
publicStringname;
privateintage;
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicintgetAge(){
returnage;
}
publicvoidsetAge(intage){
this.age=age;
}
publicPerson(){
}
publicPerson(Stringname,intage){
this.name=name;
this.age=age;
}
@Override
publicStringtoString(){
return"Person{"+
"name='"+name+'\''+
",age="+age+
'}';
}
publicStringgreet(Stringname){
return"hello"+name+".";
}
}
classTeacherextendsPerson{
}
Constructor类
java.lang.reflect.Constructor类是java.lang.reflect.Executable类的直接子类,用于表示类的构造方法。通过Class对象的getConstructors()方法可以获得当前运行时类的构造方法
publicclassMyConstructor{
publicstaticvoidmain(String[]args)throwsException{
Classc=(Class)Class.forName("reflect.Person");
//Objectperson2=c.newInstance();//@Deprecated
//System.out.println(person2);
Constructorconstructor=c.getConstructor();
Personperson=constructor.newInstance();
System.out.println(person);
//获取public有参构造方法
Constructorconstructor1=c.getConstructor(String.class,int.class);
Personperson1=constructor1.newInstance("JL",18);
System.out.println(person1);
//获取构造方法
Constructorconstructor2=c.getDeclaredConstructor(String.class,int.class);
constructor2.setAccessible(true);
Personperson2=constructor1.newInstance("JL",18);
System.out.println(person2.name);
}
}
Field类
java.lang.reflect.Field类用于封装成员变量信息,调用Class对象的getField()或getFields()等方法可以获得当前运行时类的成员变量
publicclassMyField{
publicstaticvoidmain(String[]args)throwsException{
Class>c=Class.forName("reflect.Person");
//在Person类中,无参的构造方法不能省略
Objectp=c.getConstructor().newInstance();
//获取public成员变量
Field[]fields=c.getFields();
//获取所有成员变量(包括private)
Field[]allFields=c.getDeclaredFields();
//获取指定名称public变量
Fieldf1=c.getField("name");
//成员变量set、get
f1.set(p,"JL");
System.out.println(f1.get(p));
Fieldf2=c.getDeclaredField("age");//privateintage
//忽略权限检查,使得private成员可以被访问
f2.setAccessible(true);
f2.set(p,18);
System.out.println(f2.get(p));
}
}
Method类
java.lang.reflect.Method类是java.lang.reflect.Executable类的直接子类,用于封装成员方法的信息,调用Class对象的getMethod()方法或getMethods()方法可以获得当前运行时类的指定方法或所有方法
publicclassMyMethod{
publicstaticvoidmain(String[]args)throwsException{
Classc=(Class)Class.forName("reflect.Person");
Personp=c.getConstructor().newInstance();
//获取所有public方法
Method[]methods=c.getMethods();
//获取greet方法
Methodmethod1=c.getMethod("greet",String.class);
//执行greet方法
System.out.println(method1.invoke(p,"JL"));
}
}
0
PS:主要简单说明反射的使用,关于类加载机制,性能分析等没有说明
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。