Java中的反射机制

 反射是Java程序开发语言的特征之一。它允许动态地发现和绑定类、方法、字段,以及所有其他的由语言所产生的元素。

归纳起来,Java反射机制主要提供了以下功能:

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

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

3、在运行时判断任意一个类所具有的成员变量和方法;

4、在运行时调用任意一个对象的方法。通过反射甚至可以调用到private的方法;

Java反射所需要的类并不多,主要有java.lang.Class类和java.lang.reflect包中的FieldConstructorMethodArray类。

Class类:Class类的对象表示正在运行的 Java 应用程序中的类和接口。

Field:提供有关类或接口的属性的信息,以及对它的动态访问权限。反射的字段可能是一个类属性或实例属性,简单的理解可以把它看成一个封装反射类的属性的类。

Constructor:提供关于类的单个构造方法的信息以及对它的访问权限。它封装了反射类的构造方法。 

Method:提供关于类或接口上单独某个方法的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。它是用来封装反射类方法的一个类。

Array:提供了动态创建数组和访问数组的静态方法。该类中的所有方法都是静态方法

注意:Class类是Java反射的起源,针对任何一个你想探勘的类,只有先为它产生一个Class类的对象,接下来才能通过Class对象获取其他想要的信息。

获得Class对象

调用Object类的getClass()方法来得到Class对象,这也是最常见的产生Class对象的方法。例如,
MyObject x=new MyObject();
Class c1 = x.getClass();

使用Class类的forName()静态方法获得与字符串对应的Class对象。Class c2=Class.forName("java.lang.String");
注意:参数字符串必须是类或接口的完全限定名。

使用类型名.class获取该类型对应的Class对象。例如,Class cl1 = Manager.class;
Class cl2 = int.class;    Class cl3 = double[].class;

获取类型信息

要在运行时获取某个类型的信息,需先获取这个类型所对应的Class对象,然后调用Class类提供的相应方法来获取。

获取指定类对应的Class对象
Class clazz = Class.forName("java.util.ArrayList");

获取指定类的包名clazz.getPackage()获取此Class对象所对应的实体所在的包的信息描述类java.lang.Package的一个对象。
String packageName = clazz.getPackage().getName();

获取指定类的修饰符
通过Class对象的getModifiers()方法可以获取此Class对象所对应的实体的用整数表示的类修饰符值。
int mod = clazz.getModifiers();
String modifier = Modifier.toString(mod);

获取指定类的完全限定名
className = clazz.getName();

获取指定类的父类
superClazz = clazz.getSuperclass();

获取指定类实现的接口
通过Class对象的getInterfaces()方法可以获取此Class对象所对应的实体实现的所有接口的Class对象数组。Class[] interfaces = clazz.getInterfaces();

获取指定类的成员变量
通过Class对象的getFields()方法可获取此Class对象所对应的实体的所有public字段(成员变量)。如果要获取所有字段,可以使用getDeclaredFields()方法。

注意:方法返回的是java.lange.reflect.Field类的对象数组。Field类用来代表字段的详细信息。通过调用Field类的相应方法可以获取字段的修饰符、数据类型、字段名等信息。

for (Field field : fields) {

   String modifier = Modifier.toString(field.getModifiers());

   Class type = field.getType();

   String name = field.getName();

   if(type.isArray()){

      String arrType = type.getComponentType().getName() + "[]";

            System.out.println("  "+modifier+" "+arrType+" "+name+";");

   }else{

         System.out.println("   "+modifier+" "+type+" "+name+";");

   }

}

获取类的构造方法
通过Class对象的getConstructors()方法可获取该Class对象所对应的实体的所有public构造方法。如果要获取所有的构造方法,可以使用getDeclaredConstructors()方法。
Constructor[] constrcutors = clazz.getDeclaredConstructors();

注意:方法返回的是java.lang.reflect.Constructor类的对象数组。Constructor类用来代表类的构造方法的相关信息。通过调用Constructor类提供的相应方法也可以获取该构造方法的修饰符、构造方法名、参数列表等信息。

for (Constructor constructor : constrcutors) {

   String name = constructor.getName();

   String modifier = Modifier.toString(constructor.getModifiers());

   System.out.print("    " + modifier + " " + name + "(");

   Class[] paramTypes = constructor.getParameterTypes();

   for (int i = 0; i < paramTypes.length; i++) {

      if(i > 0){    System.out.print(", ");     }

      if(paramTypes[i].isArray()){

      System.out.println(paramTypes[i].getComponentType().getName() + "[]");

      }else{

        System.out.print(paramTypes[i].getName());

      }

   }

   System.out.println(");");

}

获取类的成员方法
通过Class对象的getMethods()方法获取到的是该Class对象所对应的实体的所有public成员方法。如果要获取所有成员方法,可以使用getDeclaredMethods()方法。
Method[] methods = clazz.getDeclaredMethods();

注意:方法返回的是java.lang.reflect.Method类的对象数组。Method类用来代表类的成员方法的相关信息。通过调用Method类提供的相应方法也可以获取该成员方法的修饰符、返回值类型、方法名、参数列表等信息

 

使用无参构造方法
如果要使用无参的构造方法创建对象,只需调用这个类对应的Class对象的newInstance()方法。
Class c = Class.forName("java.util.ArrayList");
List list = (List) c.newInstance();

需要注意的是:如果指定名称的类没有无参构造方法,在调用newInstance()方法时会抛出一个NoSuchMethodException异常。

使用带参数的构造方法
要使用带参数的构造方法来创建对象,可以分为如下3个步骤来完成。

1  获取指定类对应的Class对象。

2  通过Class对象获取满足指定参数类型要求的Constructor对象。

3  调用指定Constructor对象的newInstance方法,传入对应的参数值,创建对象。

java.util.Date类有一个带参数的构造方法,它需要一个long类型的参数,编写程序通过反射使用java.util.Date类的带参构造方法来创建对象。

 

调用方法
使用反射可以取得指定类的指定方法的对象代表,方法的对象代表就是java.lang.reflect.Method类的实例,通过Method类的invoke方法可以动态调用这个方法。
public Object invoke(Object obj, Object... args) throws IllegalAccessException,IllegalArgumentException, InvocationTargetException

该方法的第一个参数是一个对象类型,表示要在指定的这个对象上调用这个方法

第二个参数是一个可变参数,用来给这个方法传递参数值;

invoke方法的返回值用来表示动态调用指定方法后的实际返回值。

注意:若要通过反射调用类的某个私有方法,可以在这个私有方法对应的Method对象上,先调用setAccessible(true)来取消Java语言对本方法的访问检查,然后再调用invoke方法来真正执行这个私有方法。

 

Properties文件的处理

Java中的properties文件是一种配置文件,主要用于表达配置信息,文件类型为*.properties,格式为文本文件,文件的内容是格式是=的格式,也就是说文件的每一行都是先定义一个键名,然后等于号后面是值,在properties文件中,可以用“#”来作注释,

properties文件在Java编程中用到的地方很多,操作很方便。最常见的操作该类文件的方法是通过Properties类来完成。

JDK 中的 Properties 类存在于包java.util 中,该类继承自 Hashtable ,主要方法包括:

getProperty(String key):用指定的键在此属性列表中搜索属性。也就是通过参数 key ,得到key所对应的 value

load(InputStream  inStream) :从输入流中读取属性列表(键和元素对)。通过对指定的文件进行装载来获取该文件中的所有键-值对,以供getProperty(String key) 来搜索。

setProperty(String  key, String  value):调用Hashtable的方法put。来设置-对。

store(OutputStream out, String comments):以适合使用load方法加载到Properties表中的格式,将此Properties表中的属性列表(键和元素对)写入输出流。

clear ():清除所有装载的-对。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值