浅谈Java的反射机制
来源:互联网 发布:淘宝刷单怎么被发现 编辑:程序博客网 时间:2024/04/28 15:57
概述
Java反射是可以让我们在运行时获得类的方法、属性、父类、接口等类的内部信息的机制。也就是说反射本身是一个“反着来”的过程。我们通过new创建类的实例时实际上是JVM在运行时根据这个类的class对象构建出来的,而反射是在运行时通过类的class对象获得他的内部定义信息。
Class类
我们知道使用javac能够将.java文件编译成.class文件,这个.class文件包含了我们对类的原始定义信息(构造函数、方法、属性、父类、接口等)。我们又知道.class文件在运行时会被类加载器(ClassLoader)加载到JVM中,当一个.class文件被加载后,JVM会为之生成一个class对象,我们在程序中通过new实例化的对象实际上是在运行时根据相应的class对象构造出来的。确切的说这个class对象是java.lang.Class<T>泛型类的一个实例比如Class<Human>对象即为一个封装了Human类的定义信息的Class<T>实例。由于java.lang.Class<T>类不存在公有构造函数,因此我们不能直接实例化这个类,我们可以通过一下方法获得一个class对象。例如我们定义了一个Human类
class Human { private String sex;//性别 private Integer age;//年龄 public Human(String sex,Integer age){ this.sex=sex; this.age=age; } public void eat(){//吃饭行为 System.out.println("吃早餐"); }}
1)通过类名获取其class对象
Class<Human> humanClass=Human.class;2)通过类的完整路径名获取其class对象
try { Class<Human> humanClass2=(Class<Human>) Class.forName("javaBasic.Human");} catch (ClassNotFoundException e) { e.printStackTrace(); }3)通过对象本身获取其class对象
Human h=new Human();Class<Human> humanClass3=(Class<Human>) h.getClass();通过反射获取类中定义的内部信息
1) 获取类构造器
一旦我们获得了Human的class对象,我们就能够通过这个class对象获得Human类的原始定义信息,首先我们来获取Human类的构造器对象,有了构造器对象我们就能够构造出一个Human对象出来。注意,当通过反射获取到类的 Constructor、Method、Field对象后,在调用这些对象的方法之前,先将此对象的 accessible 标志设置为 true,以取消 Java 语言访问检查,可以提升反射速度。
Class<Human> humanClass=Human.class;try {Constructor<Human> c=humanClass.getConstructor(String.class,Integer.class); c.setAccessible(true); Human human=c.newInstance("男","21");human.eat();} catch (Exception e) {e.printStackTrace();}
2) 获取类中定义的方法
要获取当前类中定义的方法可以用Class中的getDeclareMethods函数,他会获得当前类中定义的所有的方法(包括public、private、static等方法),它会返回一个Method对象数组,其中每一个Method的对象即表示类中定义的一个方法。要想获得类中定义的指定的方法可以用getDeclareMethod(Stirng name,Class...<T>parameterType)。
try {Class<Human> humanClass=Human.class;Human human=humanClass.newInstance();//初始化对象Method[] methods=humanClass.getDeclaredMethods();for(Method method:methods){System.out.println("方法名:"+method.getName());}//获得指定的方法Method eat=humanClass.getDeclaredMethod("eat", String.class);if(Modifier.isPrivate(eat.getModifiers())){//判断eat()的作用域是否为私有System.out.println("private");}eat.invoke(human);//调用eat()方法} catch (Exception e) {e.printStackTrace();}3)获取类中定义的属性
获取属性和获取方法类似,只不过将getMethod()换成了getField(),getDeclaredMethod()换成了getDeclareField()。
try {Class<Human> humanClass=Human.class;Field[] fields=humanClass.getDeclaredFields();for(Field field:fields){System.out.println("属性名:"+field.getName());}//获得指定的属性Field sex=humanClass.getDeclaredField("sex");} catch (Exception e) {e.printStackTrace();}4)获取父类和接口
我们先定义一个子类Man去继承Human类,如下,
class Man extends Human{private String beard;//有胡子@Override public void eat(){//吃饭行为 System.out.println("只吃午餐"); }}然后通过class对象的getSuperClass()得到man的父类,通过getInterFaces获取接口。
Class<Man> manClass=Man.class;Class<?> humanClass= manClass.getSuperclass();Class<?>[] interfaces = manClass.getInterfaces();for (Class<?> i : interfaces) { System.out.println(i.getName());}总结
Java 反射是可以让我们在运行时获取类的函数、属性、父类、接口等 Class 内部信息的机制。通过反射还可以让我们在运行期实例化对象,调用方法,通过调用 get/set 方法获取变量的值,即使方法或属性是私有的的也可以通过反射的形式调用,这种“看透 class”的能力被称为内省,这种能力在框架开发中尤为重要。 有些情况下,我们要使用的类在运行时才会确定,这个时候我们不能在编译期就使用它,因此只能通过反射的形式来使用在运行时才存在的类(该类符合某种特定的规范,例如 JDBC),这是反射用得比较多的场景。
还有一个比较常见的场景就是编译时我们对于类的内部信息不可知,必须得到运行时才能获取类的具体信息。比如 ORM 框架,在运行时才能够获取类中的各个属性,然后通过反射的形式获取其属性名和值,存入数据库。这也是反射比较经典应用场景之一。
- java的反射机制浅谈
- java的反射机制浅谈
- 浅谈Java的反射机制
- java的反射机制浅谈
- java的反射机制浅谈
- java的反射机制浅谈
- java的反射机制浅谈
- java的反射机制浅谈
- java的反射机制浅谈
- java的反射机制浅谈
- 浅谈Java的反射机制
- Java的反射机制浅谈
- JAVA的反射机制浅谈
- 浅谈Java的反射机制
- java的反射机制浅谈
- java的反射机制浅谈
- java的反射机制浅谈
- 浅谈JAVA反射机制
- 三、文件搜索命令【基础篇】
- 将HTML5封装成android应用APK文件的几种方法
- Android开发艺术探索——IPC之Messenger、AIDL
- gridview 点击行变颜色
- JAVA文件操作大全(5)
- 浅谈Java的反射机制
- iOS- define宏定义和const常变量区别
- Elasticsearch与Solr
- Python open和read功能的不同返回对象
- nginx的配置、虚拟主机、负载均衡和反向代理
- 读书笔记-《大话数据结构》第一章数据结构绪论
- url中含有中文字符
- OpenGL学习笔记(一)
- httpd.conf文件配置详解