java第五篇java反射的学习

来源:互联网 发布:二次元图片软件 编辑:程序博客网 时间:2024/06/10 01:22

1.java反射是什么?

    java反射机制:指的是程序运行时能够获取自身的信息。在Java中只要给定类的名字,那么就可以通过反射机制来获取类的所有信息。

2.反射有什么用?

    增加程序的灵活性,避免将程序写死到代码里.    优点:可以实现动态创建对象和编译,体现出很大的灵活性。

3.反射一般用在哪里?

    一般用在框架体层比较多,如:初始化一些程序配置,配置文件properties可以由用户自己修改,这样就不需要一有问题就发新包给用户,    让用户进行卸载更新应用程序,提高了灵活性。*不过直接读取properties配置文件即可,为啥还需要用反射呢?*    拿到properties,这样的话你想取里面的值就需要在应用的全局变量中存储properties,否则每次都要去getProperties(),    然后根据properties.getProperty("name"),这样子很麻烦,可以直接把配置文件中的内容反射到一个类里,这个类专门存放与配置    文件相应的变量,这样我们代码中就可以通过类的变量来获取properties配置文件中的值。

4.如何使用反射?

第一步:获取Class对象。Class类:Java中java.lang.Class类用于表示一个类的字节码(.class)文件.如何得到某个class文件对应的Class对象    已知类和对象的情况下        类名.class         对象.getClass() ---- Object类提供    未知类和对象的情况下        Class.forName(“包名.类名”) Class类代表某个类的字节码,并提供了加载字节码的方法:forName(“包名.类名”)forName方法用于加载类字节码到内存中,并封装成一个Class对象.第二步:通过Class对象中的方法获取类中构造方法、成员变量、方法,拿到后对外提供都是对象,有Constructor、Field、Method对象。    1.创建实例(获得构造器).    Constructor类        Constructor类的实例对象代表类的一个构造方法    得到某个类所有的构造方法        Constructor [] constructors=        Class.forName("java.lang.String").getConstructors();    得到指定的构造方法并调用        Constructor constructor = Class.forName(“java.lang.String”).getConstructor(String.class);        String str = (String)constructor.newInstance(“abc”);    Class类的newInstance()方法用来调用类的默认构造方法        String obj =(String)Class.forName("java.lang.String").newInstance();

1).class.newInstance()创建实例,相对于无参数的构造方法,如:
Person p = (Person)clazz.newInstance();

2).Constructor c = class.getConstructor(int.class,String.class);//创建实例,相对于一个带(int,String)参数的有参构造方法.
//通过构造器来创建实例。
Person p2 = (Person)c.newInstance(28,”张三”);

3)class.getConstructors();//获取说有构造器。

    2.获取属性的对象。    Field类        Field类代表某个类中的一个成员变量,并提供动态的访问权限        Field对象的获得        得到所有的成员变量        Field[] fields = c.getFields(); // 取得所有public属性(包括父类继承)        Field[] fields = c.getDeclaredFields(); // 取得所有声明的属性        得到指定的成员变量        Field name = c. getField("name");        Field name = c. getDeclaredField("name");        设置Filed变量是否可以访问        field. setAccessible(boolean);        Field变量值的读取、设置        field.get(obj)        filed.set(obj,value);

获取属性:
1).class.getField(“name”);//获取公有的name的属性,即Person类中的name属性必须声明为public才行,如果是private String name声明为private私有的,获取不到。

2).Field name = class.getDeclaredField(“name”);//可以获取公有的和私有的
//拿到name的属性之后,可以设置属性的内容
name.setAccessible(true);//设置操作属性,就是允许你去操作name属性,因为name是私有的,你不是他,你操作不了。
//设置属性内容,需要传一个实例
Person person = (Person)class.newInstansnce();
name.set(person,”张三”);//这句话相当于 p.name = “张三’;

//获取属性值
System.out.println(name.get(person));//输出: 张三
//获取属性名称
System.out.println(name.getName());//输出: name

    3.获取方法的对象。        Method类            Method类代表某个类中的一个成员方法            Method对象的获得            获得所有方法             getDeclaredMethods()             getMethods()            获得指定的方法            getDeclaredMethod(String?name, Class<?>...?parameterTypes)             getMethod(String?name, Class<?>...?parameterTypes)             m.setAccessible(true);            通过反射执行方法            invoke(Object?obj, Object...?args)             注意:如果执行static方法 ,第一个参数obj 传入 null

获取方法:
1).Method m = class.getDeclaredMethod(“setName”,String.class);//获取公有的和私有的方法
m.setAccessible(true);

Person p = (person)clazz.newInstance();
m.invoke(p,”张三”);//相当于 p.setName(“张三”);

//获取方法名称
System.out.println(m.getName());//输出: setName

其他方法:

        boolean isArray():是否为数组类型;      ? boolean isAnnotation():是否为注解类型;      ? boolean isAnnotationPresent(Class annotationClass):当前类是否被annotationClass注解了;      ? boolean isEnum():是否为枚举类型;      ? boolean isInterface():是否为接口类型;      ? boolean isPrimitive():是否为基本类型;      ? boolean isSynthetic():是否为引用类型;

其他反射类:

        其他反射类都在java.lang.reflect包下        1.AccessibleObject        AccessibleObject类是Constructor、Method、Field三个类的父类。        ? Annotation getAnnotation(Class annotationClass):获取作用在当前成员上的annotationClass类型的注解对象;        ? Annotation[] getAnnotations():获取作用在当前成员上的所有注解对象;        ? boolean isAccessible():判断当前成员是否可访问;        ? void setAccessible(boolean flag):设置当前成员是否可访问。        2.Construcator        ? String getName():获取构造器名;        ? int getModifiers():获取构造器上的所有修饰符信息;        ? Class getDeclaringClass():获取构造器所属的类型;        ? Class[] getParameterTypes():获取构造器的所有参数的类型;        ? Class[] getExceptionTypes():获取构造器上声明的所有异常类型;        ? T newInstance(Object… initargs):通过构造器反射对象调用构造器。        3.Method        ? String getName():获取方法名;        ? int getModifiers():获取方法上的所有修饰符信息;        ? Class getDeclaringClass():获取方法所属的类型;        ? Class[] getParameterTypes():获取方法的所有参数的类型;        ? Class[] getExceptionTypes():获取方法上声明的所有异常类型;        ? Class getReturnType():获取方法的返回值类型;        ? Object invode(Object obj, Object… args):通过方法反射对象调用方法,如果当前方法是实例方法,那么当前对象就是obj,        如果当前方法是static方法,那么可以给obj传递null。args表示是方法的参数;        ? setAccessible(true);        4.Field        ? String getName():获取属性名;        ? int getModifiers():获取属性上的所有修饰符信息;        ? Class getDeclaringClass():获取属性所属的类型;        ? Class getType():获取当前属性的类型;        ? Object get(Object obj):获取obj对象的当前属性值;        ? void set(Object obj, Object value):设置obj对象的当前属性值为value;        ? XXX getXXX(Object obj):如果当前属性为基本类型,可以使用getXXX()系列方法获取基本类型属性值。假如当前属性为int类型,        那么可以使用getInt(Object obj)方法获取obj对象的当前属性值;        ? void setXXX(Object obj, XXX value):如果当前属性为基本类型,可以使用setXXX()系统方法基本类型属性值。假如当前属性为int类型,        那么可以使用setInt(Object obj, int value)方法设置obj对象的当前属性值为value。        5.Modifier        Modifier类有一系列的static方法用来解析其他getModifiers()方法返回的int值。        Method m = …        int m = m.getModifiers();        boolean b1 = Modifier.isAbstract(m);//解析m中是否包含abstract修饰        boolean b2 = Modifier.isStatic(m);//解析m中是否包含static修饰        String s = Modifiers.toString(m);//把所有修饰都转换成字符串    其他补充:isAssignableFrom 是用来判断一个类Class1和另一个类Class2是否相同或是另一个类的超类或接口。         通常调用格式是:             Class1.isAssignableFrom (Class2)             调用者和参数都是   java.lang.Class   类型。