java反射机制

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

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

注意:反射是在运行的时候进行的,不是在编译的时候运行的。

反射的功能

Java反射机制主要提供了以下功能:

在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。API简介

在这里先看一下sun为我们提供了那些反射机制中的类:

— java.lang.Class; 代表一个类

— java.lang.reflect.Constructor; 代表类的构造方法

— java.lang.reflect.Field; 代表类的成员变量(成员变量也称为类的属性)

— java.lang.reflect.Method;代表类的方法

— java.lang.reflect.Array;提供了动态创建数组,以及访问数组的元素的静态方法

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

方法介绍

方法关键字

含义

getDeclaredMethods()

获取所有的方法

getReturnType()

获得方法的放回类型

getParameterTypes()

获得方法的传入参数类型

getDeclaredMethod("方法名",参数类型.class,……)

获得特定的方法

构造方法关键字

含义

getDeclaredConstructors()

获取所有的构造方法

getDeclaredConstructor(参数类型.class,……)

获取特定的构造方法

父类和父接口

含义

getSuperclass()

获取某类的父类

getInterfaces()

获取某类实现的接口

获取Class的三种方式

1)、使用Class类的forName(String className)静态方法。改方法需要传入字符串参数,改字符串参数的值是某个类的全限定类名(必须添加完整的包名)。

Class.forName("java.lang.String");

2)、调用某个类的class属性来获取该类对应的class对象,如

String.class

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

String s = "aa";

Class<?> clazz = s.getClass();

生成对象

1)、通过不带参数的构造方法生成对象有两种方法

a)、先获得Class对象,然后通过该Class对象的newInstance()方法直接生成即可:

newInstance()方法可以返回一个实例,但是构造方法要是没有参数列表的,它相当于调用某个类的不带参数的构造方法,但是如果在初始化对象的时候要传参数,就要使用Constructor

Class<?> classType = String.class;

Object obj = classType.newInstance();

b)、先获得Class对象,然后通过该对象获得相应的Constructor对象,再通过该Constructor对象的newInstance()方法生成:

Class<?> classType =object.getClass();

Constructor cons= classType.getConstructor(newClass[]{});

Object obj= cons.newInstance(newObject[]{});

2)、若想通过类的带参数的构造方法生成对象,只能使用下面一种方式:

Class<?> classType =object.getClass();

Constructor cons= classType.getConstructor(newClass[]{String.class,int.class});

Object obj= cons.newInstance(newObject[]{"hello",3});

例子

publicclassReflectTester

{//方法实现对Customer对象的拷贝操作publicObject copy(Object object)throwsException

{

Class<?> classType =object.getClass();/*Constructor cons = classType.getConstructor(new Class[]{});

Object obj = cons.newInstance(new Object[]{});

System.out.PRintln(obj);

System.out.println("-----------");*///以上的两行代码等价于下面一行//Object obj2 = classType.newInstance();Constructor cons2 = classType.getConstructor(newClass[]{String.class,int.class});

Object obj2= cons2.newInstance(newObject[]{"hello",3});

System.out.println(obj2);returnnull;

}publicstaticvoidmain(String[] args)throwsException {

ReflectTester test=newReflectTester();

test.copy(newCustomer());

}

}classCustomer

{privateLong id;privateintage;privateString name;publicCustomer()

{

}publicCustomer(String name,intage)

{this.name =name;this.age=age;

}publicLong getId() {returnid;

}publicvoidsetId(Long id) {this.id =id;

}publicintgetAge() {returnage;

}publicvoidsetAge(intage) {this.age =age;

}publicString getName() {returnname;

}publicvoidsetName(String name) {this.name =name;

}

}

相对复杂的例子

importjava.lang.reflect.Constructor;importjava.lang.reflect.Field;importjava.lang.reflect.Method;publicclassReflectTester

{//方法实现对Customer对象的拷贝操作publicObject copy(Object object)throwsException

{

Class<?> classType =object.getClass();

Object ObjectCopy= classType.getConstructor(newClass[]{}).newInstance(newObject[]{});//获得成员变量Field[] fields=classType.getDeclaredFields();for(Field field : fields)

{

String name=field.getName();

String firstLetter= name.substring(0,1).toUpperCase();//将属性的首字母转换为大写String getMethodName= "get" + firstLetter + name.substring(1);

String setMethodName= "set" + firstLetter + name.substring(1);

Method getMethod= classType.getMethod(getMethodName,newClass[]{});

Method setMethod= classType.getMethod(setMethodName,newClass[]{field.getType()});

Object value= getMethod.invoke(object,newObject[]{});

setMethod.invoke(ObjectCopy,newObject[]{value});

}returnObjectCopy;

}publicstaticvoidmain(String[] args)throwsException {

Customer customer=newCustomer("tom",20);

customer.setId(1L);

ReflectTester test=newReflectTester();

Customer cus=(Customer)test.copy(customer);

System.out.println(cus.getAge()+","+cus.getName()+","+cus.getId());

}

}classCustomer

{privateLong id;privateintage;privateString name;publicCustomer()

{

}publicCustomer(String name,intage)

{this.name =name;this.age=age;

}publicLong getId() {returnid;

}publicvoidsetId(Long id) {this.id =id;

}publicintgetAge() {returnage;

}publicvoidsetAge(intage) {this.age =age;

}publicString getName() {returnname;

}publicvoidsetName(String name) {this.name =name;

}

}

注意:Integer.TYPE返回的是int,而Integer.class返回的是Integer类所对应的Class对象。

反射生成多维数组

importjava.lang.reflect.Array;/***

* 用反射构造一个多维数组

**/publicclassArrayTester2 {publicstaticvoidmain(String[] args) {int[] dims =newint[]{5,10,15};//newInstance()方法的第二个参数是代表生成数组的维度,所以生成的数组维度为5,10,15,长宽高Object array =Array.newInstance(Integer.TYPE,dims);//arrayObj是一个二维的数组Object arrayObj = Array.get(array,3);

Class<?> classType =arrayObj.getClass().getComponentType();//arrayObj是一个一维的数组arrayObj = Array.get(arrayObj, 5);

Array.setInt(arrayObj,10, 37);int[][][] arrayCast = (int[][][])array;

System.out.println(arrayCast[3][5][10]);

}

}

反射访问私有(private)的方法

private 限制的方法没有办法在另外的类中使用,但可以使用反射进行使用。而getMethod()方法只能获取public的方法。如果要使用private的方法就要使用 getDeclaredMethod()方法。

例子1、获取privete方法、

publicclassPrivateTest {privateString sayHello(String name)

{return"hello" +name;

}

}

importjava.lang.reflect.InvocationTargetException;importjava.lang.reflect.Method;publicclassTestPrivate {publicstaticvoidmain(String[] args)throwsSecurityException, NoSuchMethodException, IllegalArgumentException, IllegalaccessException, InvocationTargetException {

PrivateTest p=newPrivateTest();

Class<?> classType =p.getClass();

Method method= classType.getDeclaredMethod("sayHello",newClass[]{String.class});

method.setAccessible(true);//压制java的访问控制检查String str= (String)method.invoke(p,newObject[]{"aaa"});

System.out.println(str);

}

}

例子2、改变private的属性

publicclassPrivate2 {privateString name = "zhangsan";publicString getName()

{returnname;

}

}

/***

* 将Private2中的private属性name的值变为李四

**/publicclassTestPrivate2{publicstaticvoidmain(String[] args)throwsException

{

Private2 p=newPrivate2();

Class<?> classType =p.getClass();

Field field= classType.getDeclaredField("name");

field.setAccessible(true);

field.set(p,"lisi");

System.out.println(p.getName());

}

}

致谢:感谢您的阅读!

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航