core java interview point (6)

31. 反射的作用与原理。

java反射是java被视为动态语言的一个关键性质,它允许程序在运行时候通过Reflection APIs取得任何一个自身class的内部信息,包括modifiers(public static private..)。superclass(Object),实现值interfaces(Cloneable),也包括了fields和methods的所有信息,并可运行时改变fields内容或唤起methods。

 

Reflection enables java code to discover information about the fields, methods and constructions of loaded classes, and to use reflected fields, methods, and constructions to operate on their underlying counterparts, within security restrictions. The API accommodates applications that need access to either the public members of a target object(base on its runtime class) or the members declared by a given class. It also allows programs to suppress defualt reflective access control.

 

java反射机制允许程序在运行时候加载、探知、使用编译期间完全未知的classes,换言之,java可以加载一个运行时才得知名称的class,获得其完整的结构。

通过反射,我们可以在运行时获得程序或者程序集中每个类型的成员和成员信息。程序中的对象类型一般都是在编译期间就确定下来的,但是java reflection可以动态创建对象并调用属性,这样的对象的类型在编译期间是位置的。所以我们可以通过反射机制直接创建对象,jishizhegeduxiiang类型在编译器是未知的。

反射的核心是JVM在运行时才动态的加载类或调用方法、访问属性。它不需要事先(写代码或编译期)直到运行对象是谁。

 

 

首先我们看JVM:java virtual machine,用于将java编译成.class文件,是的java的可跨平台性。本身jvm就是一个程序,用于编译java。

preview

 假设代码:Object ob = new Object();

JVM启动后,代码编译成.class文件,然后被类加载器加载进jvm的内存中,类Object加载到方法区中,创建了Object类的class对象到堆中,注意这个不是new出来的对象,而是类的class类型对象,每个类只有一个class对象,作为方法区类的数据结构的接口。JVM创建对象前,会先检查类是否加载,寻找类对应的clas对象,若加载好了,则为你的对象分配内存,初始化也就是代码new Object();

这就是自己写好的代码,JVM直接执行就好。

但是在程序运行中,类没有加载进JVM中呢?在程序运行时,需要动态的区家在一些类,这些类可能之前用不到所以不用加载到JVM,比如数据库驱动程序,它依赖于具体的数据库实现。我们只需要依据实际需要配置相关驱动,这时候程序就能动态化的实现Class clazz = Class.forName("data_driver");data_driver自己配制,这样就实现了java的动态性,java反射的一个应用。

 

作用:

在我们使用的IDE工具eclipse或者Idea,当我们输入一个对象名称或者类,想调用他的方法或者属性时候,一按点号,编译器就能自动的列出所有可选项,就是反射。

---反射最重要的用途就是:开发各种通用框架。

spring配置框架,通过xml文件配置了bean等,为了保证这些框架的通用型,就需要根据配置文件加载不同的对象或者类,调用不同的方法-反射,运行时动态加载对象。

基本应用:

java反射框架主要提供以下功能:(反射都是在运行时)

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

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

 3)在运行时判断任意一个类所具有的成员变量和方法(private也可以)

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

反射常用的类和函数,java反射机制的实现要借助于4个类:Class, Constructor, Field, Method

分别代表了:类对象,类的构造器对象,类的属性对象,类的方法对象。

Class类是所有反射的基础。

java.lang.reflectt包下:

Field类:提供类的成员属性信息

Method类:提供类的方法信息

Constractor类:提供类的构造器信息

Modifier类:修饰符工具类,用于判断和获取某个类、变量、方法的修饰符类型。

一、Class对象

1)获得Class对象:

Class.clazz = Class.forName(String className);

2)直接获取某个对象class

Class<?> clazz = Object.class;

Class<?> clazz = Integer.TYPE;

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

String s = new String("12");

Class clazz = s.getClass();

4)判断是否是某个类的实例:

java中 instanceof关键字用于判别是否是类的实例,Class对象中的isInstance()方法亦然。他是一个natice方法:

public native boolean isInstance(Object o);

5)创建实例:

 a.Class对象的newInstance()方法:Object str = s.newInstance();

 b.通过Class对象的getConstrustor获取Constructor对象,调用Constructor对象的newInstance()方法创建实例(用指定的构造器创建)。

 Class<?> s = String.class;

 Constructor con = s.getConstructor(String.class);

 Object  o = con.newInstance("12");

5)获取方法:

获取某个Classduxiiang的方法集合,主要有:

 a.getDeclaredMethods():返回类或者接口的所有方法,包括了各种权限的(共有、保护、默认、私有),  但是不包括继承的(父类)方法。

 public Mehod[] getDeclaredMethods() throw Exception;

 b.getMethods():方法返回某个类的所有public方法,包括了继承(父类)的public。

 public Method[] getMethods() throw Exception;

 c.getMethod(String, Class<<> ...):返回一个特定的方法,第一个参数是方法名称,第二个参数是后面参数  方法的参数对应的Class对象,能够获取到继承(父类)的方法。

 public Method getMethod(String name, Class<?> ... parameterType) throw Exception

6)获取构造器:

使用Class类的getConstructor()得到Constructor类的一个实例,Constructor类有一个newInstance()方法可以创建一个对象:

public T newInstance(Object ... initargs);

根据传入的参数获得对应的Constructor创建对象。

7)获取类的成员变量(属性)

getField(String name):访问公共的名字为name的成员变量(包括父类)

getDeclaredField(String name):访问类中的name名的字段(各种权限)

getFields():获取所有公共属性(父类)

getDeclaredFields():获取类中所有属性

8)调用方法:

我们从一个类中获取一个方法后,就可以invoke()调用这个方法

public Object invoke(Object clazzObj, Object ... args);

//第一个参数:对象名称,第二个参数:方法参数

猜你喜欢

转载自flycw.iteye.com/blog/2388320