zoukankan      html  css  js  c++  java
  • 十三章

    反射

    反射是java动态性最大的体现。

    动态语言动态性在运行期间,才去改变或确定编译器所确定的效果。

    java的动态性可以利用反射运行期探究和使用编译期未知的类。

    Class类(类模板类)

    类的加载机制。

    类加载:由类加载器完成,类的class文件读入内存后,就会创建一个java.lang.Class对象,一旦某个类被载入JVM中,同一个类就不会再次被载入。

    连接:把类的二进制数据合并到JRE中。

    初始化:JVM负责对类进行初始化,也就是对静态属性进行初始化。

    1.生命静态属性时指定初始值。

    2.使用静态初始化块为静态属性指定初始值。

    /*
    * 1、获取类的Class对象(其实所有的类型都有Class对象)
    */
    //1-1、根据一个实例对象(排除了基本数据类型),产生Class对象---动态性最低
    Student stu = new Student();
    Class stuClass = stu.getClass();//来自于Object的方法
    int[] array = new int[5];
    Class arrayClass = array.getClass();

    //1-2、根据类型名,获取Class对象---动态性低
    Class stuClass1 = Student.class;
    Class arrayClass1 = int[].class;
    Class intClass = int.class;//基本数据类型.class的方式是JDK1.5以后提供的
    Class voidClass = void.class;
    Class intClass1 = Integer.TYPE;//JDK1.5以前,使用基本数据类型对应的包装类.TYPE

    //1-3、根据类的字符串全类名,获取Class对象---动态性最高
    Class stuClass2 = null;
    try {
    stuClass2 = Class.forName("com.lovo.bean.Student");//字符串全类名完全可以从程序外部输入
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    }


    /*
    * 2、探究Class对象中类的信息
    */
    //2-1、探究类的声明部分
    System.out.println("package " + stuClass.getPackage().getName() + ";");//得到包名
    String allName = stuClass.getName();//得到类全名
    String simpleName = stuClass.getSimpleName();//得到类的简单名
    int classMod = stuClass.getModifiers();//得到类的修饰符
    String classModStr = Modifier.toString(classMod);//得到修饰符的字符串形式
    String superClassName = stuClass.getSuperclass().getName();//得到父类的Class对象
    Class[] allInter = stuClass.getInterfaces();//得到所有接口的Class对象
    String allInterNames = "";
    for(int i = 0; i < allInter.length; i++){
    allInterNames += allInter[i].getName();
    if(i != allInter.length - 1){
    allInterNames += ",";
    }
    }

    System.out.println(classModStr + " class " + simpleName +
    " extends " + superClassName + " implements " + allInterNames + "{");

    System.out.println("//属性");
    //2-2、属性的探究
    Field[] allFields = stuClass.getDeclaredFields();//获取所有的属性
    Field[] allPubicFields = stuClass.getFields();//获取所有的公共属性
    //探究指定的属性
    try {
    Field field = stuClass.getDeclaredField("name");//根据属性名,返回指定的属性
    Field publicField = stuClass.getField("height");//根据属性名,返回指定的公共属性
    } catch (NoSuchFieldException e) {
    e.printStackTrace();
    } catch (SecurityException e) {
    e.printStackTrace();
    }

    for(Field f : allFields){
    String fieldMod = Modifier.toString(f.getModifiers());//得到属性的修饰符
    String fieldTypeStr = f.getType().getName();//得到属性的类型名
    String fieldName = f.getName();//得到属性的名字

    System.out.println(" " + fieldMod + " " + fieldTypeStr + " " + fieldName + ";");
    }

    System.out.println();
    System.out.println("//构造");

    //2-3、探究构造方法
    Constructor[] allCons = stuClass.getDeclaredConstructors();//得到所有声明的构造
    Constructor[] allPublicCons = stuClass.getConstructors();//得到所有公共的构造
    try {
    Constructor con = stuClass.getDeclaredConstructor(String.class,int.class);//得到指定的构造
    Constructor publicCon = stuClass.getConstructor();//得到指定的公共构造
    } catch (NoSuchMethodException e) {
    e.printStackTrace();
    } catch (SecurityException e) {
    e.printStackTrace();
    }

    for(Constructor c : allCons){
    String conModStr = Modifier.toString(c.getModifiers());//得到构造的修饰符
    String conName = c.getName();//得到构造方法的名字
    Class[] parametersClassArray = c.getParameterTypes(); //得到所有的参数
    String paramStr = "";
    for(Class paramClass : parametersClassArray){
    paramStr += paramClass.getSimpleName() + ",";
    }
    if(parametersClassArray.length != 0){
    paramStr = paramStr.substring(0,paramStr.length()-1);
    }
    System.out.println(" " + conModStr + " " + conName + "(" + paramStr + ")");
    }

    System.out.println();
    System.out.println("//方法");

    //2-4、探究方法
    Method[] allMethods = stuClass.getDeclaredMethods();//得到所有声明的方法
    Method[] allPublicMethods = stuClass.getMethods();//得到所有的公共方法

    try {
    Method method = stuClass.getDeclaredMethod("answer");//得到指定的声明方法
    Method publicMethod = stuClass.getMethod("study",int.class);//得到指定的公共方法
    } catch (NoSuchMethodException e) {
    e.printStackTrace();
    } catch (SecurityException e) {
    e.printStackTrace();
    }

    for(Method m : allMethods){
    String methodMod = Modifier.toString(m.getModifiers());
    String returnStr = m.getReturnType().getName();
    String methodName = m.getName();
    String paramStr = "";
    Class[] params = m.getParameterTypes();
    for(int i = 0; i < params.length; i++){
    paramStr += params[i].getName();
    if(i != params.length - 1){
    paramStr += ",";
    }
    }

    System.out.println(" " + methodMod + " " + returnStr + " "
    + methodName + "(" + paramStr + ")");
    }
    System.out.println("}");


    /*
    * 3、使用反射获取的信息
    */
    //3-1、根据反射产生对象
    //3-1-1、通过Class对象获取Constructor对象,然后产生实例对象(好处:可以调用任意符合访问修饰符的构造方法;坏处:代码太多)
      Constructor con = null;
      try {
       con = stuClass.getConstructor(String.class);
      } catch (NoSuchMethodException e) {
     e.printStackTrace();
      } catch (SecurityException e) {
       e.printStackTrace();
      }
      try {
       Student stu1 = (Student)con.newInstance("zhang3");//使用Constructor的newInstance方法产生对象
       Student stu2 = (Student)con.newInstance("zhang3");
       System.out.println(stu1);
    System.out.println(stu2);
    } catch (InstantiationException e) {
     e.printStackTrace();
    } catch (IllegalAccessException e) {
       e.printStackTrace();
      } catch (IllegalArgumentException e) {
       e.printStackTrace();
      } catch (InvocationTargetException e) {
       e.printStackTrace();
      }
    //3-1-2、直接通过Class对象产生实例对象(好处:代码少;坏处:只能调用到公共无参构造)
    try {
       Student stu1 = (Student)stuClass.newInstance();
       System.out.println(stu1);
      } catch (InstantiationException e) {
       e.printStackTrace();
      } catch (IllegalAccessException e) {
       e.printStackTrace();
      }

    //3-2、根据反射调用方法
      try {
       Method m = stuClass.getMethod("study",int.class);
    m.invoke(null,4);//使用Method对象提供的invoke方法,调用Method所代表的方法
      } catch (NoSuchMethodException e) {
     e.printStackTrace();
      } catch (SecurityException e) {
       e.printStackTrace();
      } catch (IllegalAccessException e) {
       e.printStackTrace();
    } catch (IllegalArgumentException e) {
       e.printStackTrace();
    } catch (InvocationTargetException e) {
       e.printStackTrace();
      }

    //3-3、根据反射操作属性
    try {
    Field f = stuClass.getField("height");
    f.set(stu,1.8f);//用set方法赋值
    System.out.println(f.get(stu));//用get方法取值

    } catch (NoSuchFieldException e) {
    e.printStackTrace();
    } catch (SecurityException e) {
    e.printStackTrace();
    } catch (IllegalArgumentException e) {
    e.printStackTrace();
    } catch (IllegalAccessException e) {
    e.printStackTrace();
    }


  • 相关阅读:
    IIS运行asp程序出现The requested resource is in use 和 安装.net 2.0 后运行2.0程序出现 Failed to access IIS metabase 错误的解决
    动态sql语句基本语法
    屏蔽浏览器关闭按钮及ALT+F4 快捷键
    [转]如何进行.NET高效开发
    HttpRuntime.Cache 与HttpContext.Current.Cache的疑问
    我搜集的关于工作流方面的技术文章
    [转]输入框自动完成,模仿IE的,支持FireFox
    javascript 的面向对象特性参考
    定义局部变量时,字符串不能超过8000的方法
    世联地产软件工程师笔试试题
  • 原文地址:https://www.cnblogs.com/gujinshu-wangdan/p/5250082.html
Copyright © 2011-2022 走看看