JAVA反射_笔记

2017-03-10  本文已影响0人  bboymonk

在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类:
自定义注解:
上一篇 下一篇

猜你喜欢

热点阅读