黑马程序员——java—反射

来源:互联网 发布:小语网络加速器破解版 编辑:程序博客网 时间:2024/04/28 14:12

———–android培训、java培训、java学习型技术博客、期待与您交流!————

反射
1 Class类的概述:
通常所说的类是就是把一类事物中共有的属性和行为抽象出来,相当于一个模板,把这个模板称之为类
在java中有很多类事物,所有就有很多的模板,每一个模板就对应各一个类,
然而这些很多的类(模板)也会有相同东西,在把类中的相同的东西抽象出来就是Class这个类

 其中模板用官方的话说,是一个个的class文件(字节码文件),就是源代码经过编译之后产生的文件

2 Class类中的属性
Class类中就包含属性有field(字段)、method(方法)、construction(构造函数)
3 获取class文件对象的三种方法:

//persion类已经存在public class reflact{    public static void main(String[] args ) throws ClassNotFoundException    {        Persion p=new Persion();        //获得Class对象的第一种方法        Class class1=p.getClass();        //获得Class对象的第二种方法        Class class2=Persion.class;        //获得Class对象的第三种方法        Class class3=Class.forName("com.itheima.Persion");        //这里的参数是一个String类型的,需要的是Persion这个类,需要加包名字        //第三种方法在开发中最常用:       // 因为我们只需要通过配置文件提供类的路径或者方法供我们使用    }}

4 通过class文件对象,去传创建class对象
方法:
public T newInstance()–创建此 Class 对象所表示的类的一个新实例

package com.itheima;public class reflact{    public static void main(String[] args ) throws     InstantiationException, IllegalAccessException, ClassNotFoundException    {        //获得Persion类的class对象        Class class1=Class.forName("com.itheima.Persion");        //通过class对象来创建Persion类的实例对象        Object  object=class1.newInstance();        //用的是Persion类的无参构造方法    }}

5 通过反射获得构造方法并创建对象
Constructor类

package com.itheima;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;public class reflact{    public static void main(String[] args ) throws     InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException    {        //获得Persion类的class对象        Class class1=Class.forName("com.itheima.Persion");        //通过class对象来创建Persion类的实例对象        Object  object=class1.newInstance();        //获得构造 方法有四种方法可以使用        //方法一:得到Persion类中的指定的单个公共构造方法(可以使带参数的,也可以是无参的)        Constructor con1=class1.getConstructor();        Object obj1=con1.newInstance();//创建对象        Constructor con2=class1.getConstructor(String.class,int.class);        Object obj2=con2.newInstance("张三",20);//创建对象        //方法二:得到Persion类中的指定的单个私有构造方法(可以使带参数的,也可以是无参的)        Constructor con3=class1.getDeclaredConstructor(String.class,int.class,String.class);        con3.setAccessible(true);//因为是私有的,所有要取消Java语言访问检查        Object obj3=con3.newInstance("张三",20,"上海");        //方法三:得到Persion中所有公共的构造方法        Constructor[] array1=class1.getConstructors();        //方法四:得到Persion中所有的构造方法(包括私有的)        Constructor[] array2=class1.getDeclaredConstructors();    }}

6 通过反射获得成员变量并使用
Field类

package com.itheima;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;public class reflact{    public static void main(String[] args ) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException     {        //获得Persion类的class对象        Class class1=Class.forName("com.itheima.Persion");        //得到Persion类中的指定的单个公共构造方法(可以使带参数的,也可以是无参的)        Constructor con1=class1.getConstructor();        Object obj1=con1.newInstance();//创建对象        //得到Persion类中的指定的单个公共成员变量        Field f1=class1.getField("name");        f1.set(obj1, "张三");//给name成员变量赋值        //得到Persion类中的指定的单个私有成员变量        Field f2=class1.getField("address");        f2.setAccessible(true);//因为是私有的,所以要取消Java语言访问检查        f1.set(obj1, "上海");//给name成员变量赋值        //得到Persion类中所有公共成员变量        Field[] f3 =class1.getFields();        //得到Persion类中所有成员变量        Field[] f4 =class1.getDeclaredFields();    }}

7 通过反射获得成员方法并使用
Method类

package com.itheima;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class reflact{    public static void main(String[] args ) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException     {        //获得Persion类的class对象        Class class1=Class.forName("com.itheima.Persion");        //得到Persion类中的指定的单个公共构造方法(可以使带参数的,也可以是无参的)        Constructor con1=class1.getConstructor();        Object obj1=con1.newInstance();//创建对象        //得到Persion类中指定的单个公共方法(可以带参数,也可以没有)        Method m1=class1.getMethod("fun1");//这里不只有一个参数,第一个参数是方法的名字,后边可以有参数是Persion类中方法参数里边有几个参数,后边就有几个参数        m1.invoke(obj1);        //通过方法对象调用对象的方法,这里不只有一个参数,第一个参数是对象的名字,后边的参数是给该方法传的实际参数,有几个就传几个        //得到Persion类中指定的单个私有方法(可以带参数,也可以没有)        Method m2=class1.getMethod("fun2");        m2.setAccessible(true);//因为是私有,所有取消java的访问检查        m1.invoke(obj1);//通过方法对象调用对象的方法        //得到类中所有公共的方法(包括父亲的公共方法)          Method[] m3=class1.getMethods();        //得到类中所有的方法(包括私有)(不包括父亲的公共方法)        Method[] m4=class1.getDeclaredMethods();    }}

8 为了保证程序的可维护性,通过配置文件类写代码
首先创建一个配置文件,文件的名字为classes.properties
文件的内容:
className=包名.类名
MethodName=包名.类名.方法名

        Properties pop=new Properties();//创建一个配置文件的集合对象Properties继承HashTabl        pop.load(new FileReader("persion.properties"));//按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)        //获得键值对        String className=pop.getProperty(className);        Class class1=Class.forName(className);        Constructor con1=class1.getConstructor();        Object obj1=con1.newInstance();//创建对象        //得到方法,使用方法        Method m=class1.getMethod(methodName);        m.invoke(obj1);

9
反射可以越过泛型检查(泛型是给编译器看的)

需求:ArrayList array=new ArrayList();
有这样一个集合,集合的泛型是Integer类型,现需要向此集合中存放任意类型数据

 ---利用反射       ArrayList<Integer> array=new ArrayList<Integer>();       Class c=Class.forName("ArrayList");       Method m1=c.getMethod("add",Object.class);       m1.invok(array,"Hallo");       m1.invok(array,"java");

10
数组的反射

1、具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象。数组字节码的名字:有[和数组对应类型的缩写,如int[]数组的名称为:[I

2、Object[]与String[]没有父子关系,Object与String有父子关系,所以new Object[]{“aaa”,”bb”}不能强制转换成new String[]{“aaa”,”bb”}; Object x =“abc”能强制转换成String x =“abc”。

3、如何得到某个数组中的某个元素的类型,

    例:          int a = new int[3];Object[] obj=new Object[]{”ABC”,1};    无法得到某个数组的具体类型,只能得到其中某个元素的类型,    如:           Obj[0].getClass().getName()得到的是java.lang.String。

4、Array工具类用于完成对数组的反射操作。

    Array.getLength(Object obj);//获取数组的长度    Array.get(Object obj,int x);//获取数组中的元素

5、基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用;非基本类型的一维数组,既可以当做Object类型使用,又可以当做Object[]类型使用。

———–android培训、java培训、java学习型技术博客、期待与您交流!————

0 0