java的反射机制(备忘)

来源:互联网 发布:梦龙软件 编辑:程序博客网 时间:2024/05/02 05:04

一、概述

了解

1.使用反射访问方法和属性

2.使用反射动态创建和访问数组

理解

1.反射的概念和应用场合

2.使用反射获取类的信息

3.使用反射创建对象

二、反射机制 

1、反射的概念

在java中的反射机制是指在运行状态中,对于任意一个,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动获取信息以及动态调用对象方法的功能称为java语言的反射机制。

在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。

好吧,这句话太正式了,我不是很理解,然后我在网上搜了哈,参考别人的理解,就是我们可以在java程序运行时加载、探知、使用编译期间完全未知的classes,

也就是能够看透class的能力,就是java的反射机制。实际上说白了,之前不是说private修饰的类成员,不能被类以外的类或对象访问吗,而反射就可以访问private修饰的类成员,也就是说利用java的反射机制,可以随便的访问类或对象的成员(不在乎它的访问级别)和它的构造方法。


2、java反射的三个动态性质

1) 运行时生成动态对象;

2) 运行期间调用方法;

3) 运行时更改属性。

3、java反射可以实现的功能

1) 在运行时判断任意一个对象所属的类;

2) 在运行时构造任意一个类的对象;

3) 在运行时判断任意一个类所具有的方法和属性;

4) 在运行时调用任意一个对象的方法;

5) 生成动态代理;(这个见动态代理)

4、java反射的应用场合

Java程序中许多对象在运行时都会出现两种类型:编译时类型运行时类型,编译时的类型由声明该对象时使用的类型决定,运行时的类型由实际赋给该对象的类型决定,如:


此时p的编译时类型为Person,运行时类型为Student;因为对象p是引用类型,在编译时其类型由Person来确定,而在程序运行后发现p引用的内容实际是Student,因为只有在程序运行的时候才能知道p引用的内容改为了Student,所以称为运行时类型

除此之外,程序在运行时还可能接收到外部传入的一个对象,该对象的编译时类型是Object,但程序又需要调用该对象运行时类型的方法。为了解决这些问题,程序需要在运行时发现对象和类的真实信息。然而,如果编译时根本无法预知该对象和类可能属于哪些类,程序只能依靠运行时信息来发现该对象和类的真实信息,此时就必须使用反射

就是一句话,什么时候用反射,就是在编译的时候无法预知该对象和类可能属于哪些类,程序只能依靠运行时信息来发现该对象和类的真实信息。这时就需要使用反射。

5、java反射API介绍

Java中用于反射的相关类都是在java.lang.reflect包中

Class类

反射的核心类,可以获取类的属性、方法等内容信息

Field类

表示类的属性,可以获取和设置类中属性的值

Method类

表示类的方法,它可以用来获取类中方法的信息,或者执行方法。

Constructor类

表示类的构造方法

Array类

Array类提供了动态创建和访问java数组的方法

5、使用反射机制的步骤

1) 获得想操作的类的java.lang.Class对象;

2) 调用Class的方法;

3) 使用反射API来操作这些信息;

7、获取Class对象的方式

我们已经知道,每个类被加载后,系统就会为该类生成一个对应的Class对象,通过该Class对象就可以访问到java虚拟机中的这个类。Java程序中获得Class对象通常有如下三种方式:

(1)调用某个对象的getClass()方法


(2)调用某个的class属性来获取该类对应的Class对象


(3)使用Class类的forName()静态方法


注:(2)和(3)都是根据类来取得该类的Class对象,但相比之下,调用某个类的class属性来获取该类对应的Class对象这种方式有如下两种优势:

² 代码更安全,程序在编译阶段就可以检查需要访问的class对象是否存在;

² 程序性能更高,因为这种方式无需调用方法,所以程序的性能更好。


一般情况下,我们都选择.class来获取类,但如果我们只有一个表示类的全名的字符串,而我们不知道这个字符串的具体内容,此时,我们只能使用Class类的forName()方法来获取该字符串对应的Class对象。不过在使用Class类的forName()方法获取Class对象时,该方法可能会抛出一个ClassNotFoundException异常。


8、从Class类中获取信息

(1)访问Class对应的类所包含的构造方法





(2)访问Class对应的类所包含的方法

方法1

Method getMethod(String name,Class[] params)

返回此Class对象所表示的类的指定的public方法,name参数用于指定方法名称,params参数是按声明顺序标识该方法参数类型的Class对象的一个数组。

例:c.getMethod(“info”,String.class);

    c.getMethod(“info”,String.class,Integer.class);


方法2

Method[] getMethods();

返回此Class对象所表示的类的所有public方法。

方法3

Method getDeclaredMethod(String name,Class[]params);

返回此Class对象所表示的类的指定的方法,与方法的访问级别无关。

方法4

Method[] getDeclaredMethods();

返回此Class对象所表示的类的全部方法,与方法的访问级别无关。

(3)访问Class对应的类所包含的属性

方法1

Field getField(String name);

返回此Class对象所表示的类的指定的public属性,name参数用于指定属性名称。

例:

c.getField(“age”);


方法2

Field[] getFields();

返回此Class对象所表示的类的所有public 属性。

方法3

Field getDeclaredField(String name);

返回此Class对象所表示的类的指定属性,与属性的访问级别无关。

Field[] getDeclaredFields();

返回此Class对象所表示的类的全部属性,与属性的访问级别无关。

(4)访问Class对应的类所包含的注释

<A extends Annotation>A getAnnotation(Class<A> annotationClass)

:试图获取该Class对象所表示类上指定类型的注释;如果该类型的注释不存在则返回null。其中annotationClass参数对应于注释类型的Class对象。

Annotation[] getAnnotations();返回此元素上存在的所有注释

Annotation[] getDeclaredAnnotations();返回直接存在于此元素上的所有注释。

(5)访问Class对应的类所包含的内部类

Class[] getDeclaredClasses();

返回该Class对象所对应类里包含的全部内部类

(6)访问Class对应的类所在的外部类

Class getDeclaringClass();

返回该Class对象所在的外部类

(7)访问该Class对象所对应类所继承的父类、所实现的接口等

int getModifiers();——返回此类或接口的所有修饰符

Class[] getInterfaces();——返回该Class对象对应类所实现的全部接口

Package getPackage();——获取此类的包

String getName();——以字符串形式返回此Class对象所表示的类的名称

String getSimpleName();——以字符串形式返回此Class对象所表示的类的简

Class getSuperclass();——返回该Class所表示的类的超类对应的Class对象

9、创建对象


通过反射来生成对象,有如下两种方式

(1) 使用newInstance()创建对象

这种方式要求该Class对象的对应类有默认构造方法,而执行newInstance()方

法时实际上是利用默认构造方法来创建该类的实例

(2) 使用Constructor对象创建对象

要先使用Class对象获取指定的Constructor对象,再调用Constructor对象的

newInstance()方法来创建该Class对象对应类的实例。通过这种方式可以选择

使用某个类的指定构造方法来创建实例。

反射技术多用于框架及基础平台中,例如Spring

如果我们不想利用默认构造方法来创建java对象,而想利用指定的构造方法来

创建Java对象,则需要利用Constructor对象了,每个Constructor对应一个

构造方法,利用指定构造方法来创建java对象需要三个步骤:

获取该类的Class对象;

利用Class对象的getConstructor()方法来获取指定构造方法;

调用Constructor的newInstance()方法来创建Java对象。


注:在java中,无论生成某个类的多少个对象,这些对象都会对应于同一个Class

对象,要想使用反射,首先需要获得待处理类或对象所对应的Class对象。







原创粉丝点击