10、反射

2019-06-21  本文已影响0人  浮生若梦OvO

一、 反射格式:

           修饰符 返回值类型 方法名(数据类型... 变量)'

           {
                    函数体;
           }

注意:这里的变量其本质是一个数组。如果你写程序的时候,想用可变参数,最好把可变参数定义在末尾。

二、反射方法

       //public Constructor<?>[] getConstructors()
        Constructor[] cons = c.getConstructors();
        //  所有构造方法

       //public Constructor<?>[] getDeclaredConstructors()
       Constructor[] cons = c.getDeclaredConstructors();
          Class c = Class.forName("cn.itcast_01.Person");

          // 创建对象
          Constructor con = c.getConstructor();
          Object obj = con.newInstance();

           Method[] methods = c.getMethods();// 所有公共方法,包括父类的
           Method[] methods = c.getDeclaredMethods();// 本类的所有方法
         
          //第一种:无参数无返回值
          Method m1 = c.getMethod("show", null);
          m1.invoke(obj, null);
          System.out.println("---------------");
          //第二种:带参数无返回值
          Method m2 = c.getMethod("function", String.class);
          m2.invoke(obj, "林青霞");
          System.out.println("---------------");
          //第三种:带多个参数有返回值
          Method m3 = c.getMethod("reutrnValue", String.class,int.class);
          Object ooo = m3.invoke(obj, "林青霞",26);
          System.out.println(ooo);
          System.out.println("---------------");
          //第四种:私有方法的调用
          Method m4 = c.getDeclaredMethod("hello", null);
          m4.setAccessible(true);
          m4.invoke(obj, null)

三、反射概述和获取字节码文件的方式

JDK5新特性举例:
public static void main(String[] args) {
          //我也不知道别人要传递几个参数。
          // 只有在别人调用的时候,别人才明确。
          int a = 10;
          int b = 20;
          int result = sum(a, b);
          System.out.println(result);
          int c = 30;
          result = sum(a, b, c);
          System.out.println(result)
          int d = 40;
          result = sum(a, b, c, d);
          System.out.println(result);

          int e = 50;
          result = sum(a, b, c, d, e);
          System.out.println(result);

//将参数定义为可变参数,
     public static int sum(int... x) {
          int result = 0;
          for (int i : x) {
               result += i;
          }
          return result;     }

四、通过反射获取构造方法并使用

     Constructor con = c.getConstructor( );// 表示我使用的是无参数构造方法
      通过构造器对象创建对象
    // public T newInstance(Object... initargs);
     Object obj = con.newInstance();

c 获取有参构造方法

    //public Constructor<T> getConstructor(Class<?>... parameterTypes)
          Class[] classes = new Class[2];
          classes[0] = String.class;
          classes[1] = int.class;
        Constructor con = c.getConstructor(classes);
        //  改进版
          Constructor con = c.getConstructor(new Class[] { String.class, int.class });
         //最终版
         Constructor con = c.getConstructor(String.class, int.class);
         // 创建对象
         public T newInstance(Object... initargs)
         Object obj = con.newInstance("林青霞", 26);

五、通过反射获取成员变量并使用

          // 获取字节码文件对象
          Class c = Class.forName("cn.itcast_01.Person");

          // 获取成员变量对象
           Field[] fields = c.getFields();// 获取所有公共的成员变量
           Field[] fields = c.getDeclaredFields();// 获取所有的成员变量
         
          //获取构造器对象
          Constructor con = c.getConstructor();
          Object obj = con.newInstance();

          // 获取单个的成员变量
          Field field = c.getField("age");
         
          // obj.field = 20;
          //public void set(Object obj,Object value)
          field.set(obj, 20);//给obj对象的field字段赋值为20
        // 获取字节码文件对象
          Class c = Class.forName("cn.itcast_01.Person");

          // 创建对象
          Constructor con = c.getConstructor();
          Object obj = con.newInstance();

          // 获取年龄并赋值
          Field ageField = c.getField("age");
          ageField.set(obj, 26);

          // 获取姓名并赋值
          // NoSuchFieldException
          // Field nameField = c.getField("name");
          Field nameField = c.getDeclaredField("name");
        
          //public void setAccessible(boolean flag)
          //在访问私有成员变量时,暴力访问,不然会出现  IllegalAccessException  错误
          nameField.setAccessible(true);//你就不要限制我了。
          nameField.set(obj, "林青霞");

六、面试题

在ArrayList<Integer>的集合中添加一个String类型的对象,如何实现呢?

*通过反射实现
* 反射可以越过泛型检查。
public class ArrayListTest {
     public static void main(String[] args) throws Exception {
          ArrayList<Integer> array = new ArrayList<Integer>();
           array.add(10);
   
          // 获取字节码文件对象
          Class c = array.getClass();
          Method m = c.getMethod("add", Object.class);
          m.invoke(array, "hello");
          m.invoke(array, "world");
          m.invoke(array, "java");

          System.out.println(array);
     }
}
上一篇下一篇

猜你喜欢

热点阅读