美文网首页
JAVA反射_笔记

JAVA反射_笔记

作者: bboymonk | 来源:发表于2017-03-10 11:40 被阅读0次

    在JAVA中,一切都是对象,那么你新建的一个class也是对象吗?

    是的,新建的class也是对象,它是java.lang.Class的实例对象。
          class A{}
          A a = new A();
    1,Class c1 = a.class; // c1表示A这个类的类类型(小a是A的实例对象) ,这也说明了每一个类都有一个静态成员class;
    2,Class c2 = a.getClass(); // c2表示A这个类的类类型 ,通过该A类的对象a的getClass()方法获取。
    c1 == c2 //它们都是A类的类类型,一个类只可能是Class类的一个实例对象。 
    3, Class c3 = null;
            c3 = Class.forName("com.wjb.A"); //括号里写的是全类名
                  c2 == c3
     所以,完全可以通过类类型(c1 , c2 , c3)创建A的实例对象;
     A a = (A)c1.newInstance(); // 注意A类一定要有无参的构造方法

    编译时加载的类是:静态加载类

    运行时加载的类是:动态加载类

    知道了类类型后,可以通过c1.获取类的一些信息,方法的一些信息,成员变量的一些信息。

    集合的泛型也是一种反射,但是只在编译时有效,运行时就没有泛型了。

    Class,method,field(类,方法,成员变量)的操作都是绕过编译的一些操作。

    package javaReflect;
    import java.lang.reflect.Method;
    import java.util.ArrayList;
    /**
     * Created by wjb on 2017/3/6.
     */
    public class Demo {
        public static void main(String[] args) {
            String s = "Hello";
            ClassUtis.printMessage(s);
    
            ArrayList list1 = new ArrayList();
    
            ArrayList<String> list2 = new ArrayList<String>();
            list2.add("hello");
            Class c = list2.getClass();
            try {
                Method method = c.getMethod("add", Object.class);
                method.invoke(list2,20);  // 调用方法,绕过编译就绕过泛型了。
                System.out.println(list2.size());
                System.out.println(list2);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    list2的泛型是String类型,按道理是不能加入20的,但是绕过了编译,可以加进去。说明泛型只在编译时有效。

    对于内部类的反射使用:
          Office office = new Office();
          //获取所有的内部类
          Field[] fields = office.getClass().getDeclaredFields();
              for (Field f : fields) {
                  //设置属性可以访问
                  f.setAccessible(true);
                  //获取每一个内部类属性的全路径名
                  String name = f.getType().getName();
                  //所有内部类里面的属性名
                  Field[] fields2 = Class.forName(name).getDeclaredFields();
                  for (Field fid : fields2) {
                          //设置属性可以访问
                          fid.setAccessible(true);
                          //获取内部类属性上的注解,这里的注解是自定义的
                          XlsMeta xlsMeta = fid.getAnnotation(XlsMeta.class);
                          //获取注解里面定义的required
                          String required = xlsMeta.required();
                          //首选属性检查
                         // if (required.equals("Preferred")) {
                          //    list1.add("属性:" + fid.getName() + "\t建议不要为空\n");
                         // }
                          //必填属性检查
                         // if (required.equals("Required")) {
                           //   list2.add("属性:" + fid.getName() + "\t不能为空\n");
                         // }
                  }
              }
    
    Office类:
    自定义注解:

    相关文章

      网友评论

          本文标题:JAVA反射_笔记

          本文链接:https://www.haomeiwen.com/subject/vwpngttx.html