Java中的反射机制

Posted fsmly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中的反射机制相关的知识,希望对你有一定的参考价值。

一、反射概述

  反射机制指的是Java在运行时候有一种自观的能力,能够了解自身的情况为下一步做准备,其想表达的意思就是:在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的功能就称为java语言的反射机制。通俗点讲,通过反射,该类对我们来说是完全透明的,想要获取任何东西都可以,这是一种动态获取类的信息以及动态调用对象方法的能力。

  想要使用反射机制,就必须要先获取到该类的字节码文件对象(.class),通过该类的字节码对象,就能够通过该类中的方法获取到我们想要的所有信息(方法,属性,类名,父类名,实现的所有接口等等),每一个类对应着一个字节码文件也就对应着一个Class类型的对象,也就是字节码文件对象

  Java提供的反射机制,依赖于我们下面要讲到的Class类和java.lang.reflect类库。我们下面要学习使用的主要类有:①Class表示类或者接口;②java.lang.reflect.Field表示类中的成员变量;③java.lang.reflect.Method表示类中的方法;④java.lang.reflect.Constructor表示类的构造方法;⑤Array提供动态数组的创建和访问数组的静态方法。

二、反射之Class类

  (1)在类Object下面提供了一个方法:技术图片,此方法将会被所有的子类继承,该方法的返回值为一个Class,这个Class类就是反射的源头。那么Class类是什么呢?Class类是Java中用来表达运行时类型信息的对应类,我们刚刚也说过所有类都会继承Object类的getClass()方法,那么也体现了着Java中的每个类都有一个Class对象,当我们编写并编译一个创建的类就会产生对应的class文件并将类的信息写到该class文件中,当我们使用正常方式new一个对象或者使用类的静态字段时候,JVM的累加器子系统就会将对应的Class对象加载到JVM中,然后JVM根据这个类型信息相关的Class对象创建我们需要的实例对象或者根据提供静态变量的引用值。将Class类称为类的类型,一个Class对象称为类的类型对象。

  (2)Class有下面的几个特点:

  ①Class也是类的一种(不同于class,class是一个关键字);

  ②Class类只有一个私有的构造函数技术图片,只有JVM能够创建Class类的实例;

  ③对于同一类的对象,在JVM中只存在唯一一个对应的Class类实例来描述其信息;

  ④每个类的实例都会记得自己是由哪个Class实例所生成;

  ⑤通过Class可以完整的得到一个类中的完整结构;

  (3)刚刚说到过Class只有一个私有的构造函数,所以我们不能通过new创建Class实例 ,有下面这几种获取Class实例的方法:

  ①Class.forName("类的全限定名"),该方法只能获取引用类型的类类型对象。该方法会抛出异常(a.l类加载器在类路径中没有找到该类  b.该类被某个类加载器加载到JVM内存中,另外一个类加载器有尝试从同一个包中加载)

1 //Class<T> clazz = Class.forName("类的全限定名");这是通过Class类中的静态方法forName直接获取一个Class的对象
2 Class<?> clazz1 = null;
3 try 
4     clazz1 = Class.forName("reflect.Person");
5  catch (ClassNotFoundException e) 
6     e.printStackTrace();
7 
8 System.out.println(clazz1); //class reflect.Person

 

  ②如果我们有一个类的对象实例,那么通过这个对象的getClass()方法可以获得他的Class对象,如下所示

 1 //Class<T> clazz = xxx.getClass(); //通过类的实例获取类的Class对象
 2 Class<?> clazz3 = new Person().getClass();
 3 System.out.println(clazz3); //class reflect.Person
 4 
 5 Class<?> stringClass = "string".getClass();
 6 System.out.println(stringClass); //class java.lang.String
 7 
 8 /**
 9  * [代表数组,
10  * B代表byte;
11  * I代表int;
12  * Z代表boolean;
13  * L代表引用类型
14  * 组合起来就是指定类型的一维数组,如果是[[就是二维数组
15  */
16 Class<?> arrClass = new byte[20].getClass();
17 System.out.println(arrClass); //class [B
18 
19 Class<?> arrClass1 = new int[20].getClass();
20 System.out.println(arrClass1); //class [I
21 
22 Class<?> arrClass2 = new boolean[20].getClass();
23 System.out.println(arrClass2); //class [Z
24 
25 Class<?> arrClass3 = new Person[20].getClass();
26 System.out.println(arrClass3); //class [Lreflect.Person;
27 
28 Class<?> arrClass4 = new String[20].getClass();
29 System.out.println(arrClass4); //class [Ljava.lang.String;

 

 

 

  ③通过类的class字节码文件获取,通过类名.class获取该类的Class对象

1 //Class<T> clazz = XXXClass.class; 当类已经被加载为.class文件时候,
2 Class<Person> clazz2 = Person.class;
3 System.out.println(clazz2);
4 System.out.println(int [][].class);//class [[I
5 System.out.println(Integer.class);//class java.lang.Integer

 

三、创建运行时对象

 

四、反射获取类的属性、构造器、方法

 

五、反射的应用之动态代理

以上是关于Java中的反射机制的主要内容,如果未能解决你的问题,请参考以下文章

反射机制入门

反射机制入门

java 反射代码片段

深入理解 Java 中的反射机制

关于JAVA中的反射机制的总结

java 中反射机制和内省机制的区别是啥?