java reflect机制_Java的反射机制Reflect

简介:

动态获取类的信息、动态调用对象的方法的功能叫做:Java 的反射(Reflection)机制。

Reflection是不同于C++等静态语言,而被视为准动态语言的关键性质。反射机制允许程序在运行时,透过Reflection API取得任何一个已知的class的内部信息,(功能列表)如:

得到类型修饰符public、private等。

得到其父类superclass, 其本身的类class。

实现了哪些interface也可以得到。

获得所有的field和method,并且可以在运行时,改变field的值、调用method,但是不能获得method的定义和实现 —— 即实例化这个类,生成这个类的对象。

通过反射机制,Java可以加载一个在运行时才获得名称的class,获悉其完整的构造,并生成对象(而这个对象是JVM生成的,即new Instance。相当于通过逆推,从计算机的角度完成了,人学习并使用一个类的功能。而这种能力的术语被称为introspection内省。

实现Reflect相关的类:

在JDK中,主要由以下类来实现反射机制(获取这些类的对象),这些类(除了第一个)都位于java.lang.reflect包中:

Class类:代表一个类(即Class这个类存放Java的类:Class类的一个实例就是我们平常所说的一个类),位于java.lang包中。

Field类:代表类的成员变量 / 属性。

Method类:代表类的方法。

Constructor类:代表类的构造方法。

Array类:提供了动态创建数组,以及访问数组元素的静态方法等。

1、Class类(下面Class对象的概念和一般对象有点混乱):

Class类是整个反射机制的基础:一个类的所有对象,都对应于这个类,即一个Class对象而已。而实际上所有的类,或者说所有的Class对象都是由JVM生成。所以通过Class类的某些方法(对于Class类或者Class对象来说就是静态方法,对于不是Class对象的、一般的对象就是普通方法),可以获得指定的Class对象,也就是一个类的整个结构。之后就可以通过这个Class对象来操纵相应的类的一般对象。

Class对象不能通过new的方式创建,如上所说,有两种方法可以获取:

静态方法:Class clazz = Class.forName("java.lang.String");或者Class clazz = String.class;

普通方法getClass():String str = "";Class clazz = str.getClass(); —— 类是没有getClass方法的。

public classTesterMain {public static voidmain(String[] args) {

String pagename= "";try{//下面三种方法都是获得同一个Class对象:String

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

Class c1=pagename.getClass();

Class c2= String.class;if(c1.equals(c2) && c1.equals(c3) &&c2.equals(c3)) {

System.out.println("test1");

}

}catch(ClassNotFoundException e) {

e.printStackTrace();

}

}

}

2、Field类:

一个类中的每个属性都对应于一个Field对象。

importjava.lang.reflect.Field;importEntity.Test;public classTesterMain {public static voidmain(String[] args) {try{//Test类:public String testPublic;private String testNonPublic;

Class clazz = Test.class;//一 :

Field publicField = clazz.getField("testPublic");//获取指定的public属性

Field everyWhereField = clazz.getDeclaredField("testNonPublic");//获取指定的任何属性(不论限定符)

System.out.println(publicField+ "\n" +everyWhereField);

System.out.println("\n");//out:public java.lang.String Entity.Test.test//private java.lang.String Entity.Test.testNonPublic//二 :

Field[] publicFields = clazz.getFields();//获取Class对象中的所有public Field对象

for(Field field : publicFields) {

System.out.println(field);

}

Field[] allFields= clazz.getDeclaredFields();//获取所有的属性(不论限定符)

for(Field field : allFields) {

System.out.println(field);

}

}catch (SecurityException |NoSuchFieldException e) {

e.printStackTrace();

}

}

}

3、Method类(下面把Method对象对应的方法,简称为Method方法):

先给出示例代码,然后解释:

String str = "hello";try{

Method method= str.getClass().getMethod("charAt", int.class);//不能用Integer,因为charAt方法接收的是int,而int和Integer的Class对象是不一样的

char c = (char) method.invoke(str, 1);

System.out.println(c);

}catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException |InvocationTargetException e) {

e.printStackTrace();

}

通过Class对象,获得Method对象的方式:

按照方法名称 + 参数类型的Class对象列表,获得某个public Method对象(包括从父类或接口继承的方法):Method getMethod(String methodName,Class> ... parameterTypes)。

获得所有的public方法(包括继承的方法):Method [] getMethods()。

若不论方法的限定符,对应的有:getDeclaredMethod(String methodName,Class> ... parameterType)和 getDeclaredMethods()。

使用Method对象:

invoke方法,用于调用Method方法,函数原型为:Object invoke(Object obj,Object ... obj),参数一:原本调用Method方法的对象,参数二:Method方法的实参列表。 —— 因此,若Method方法是static的,则参数一为null。

4、Constructor类:

5、Array类:

最后,通过反射得到了Class对象,那么就可以用Class对象构造出对应的类的实例:

//一 :默认构造函数:String string1 = new String();

Class clazz = String.class;

String string1=(String) clazz.newInstance();//二:指定的构造函数(不一定带参,自适应):String string2 = new String("hello reflect");

Constructor constructor =clazz.getConstructor();

String string2= (String) constructor.newInstance("hello reflect");

System.out.println(string1+ "\n" +string2);//out:空字符串//hello reflect

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值