1.“万事万物皆对象”,类也是对象,是java.lang.Class类的实例对象,这个对象有三种表示方式:(c1,c2表示了Student类的类类型class type,即这个对象被称之为该类的类类型)

    1)Class c1 = Student.class;     ——任何一个类都有一个隐含的静态成员变量class;

    2)Class c2 = s1.getClass();     ——已知该类对象,用getClass()方法;

    3)Class c3 = null; c3 = Class.forName("类的全称");

2. c1 == c2 (true) 不管是c1还是c2,都代表了Student类的类类型,一个类只可能是Class类的一个实例对象。

3.我们可以通过类类型,创建类的实例对象。

Student s1 = (Student)c1.newInstance();//需要有无参数的构造方法

4.Class.forName("类的全称"),不仅表示了类的类类型,还代表了动态加载类。

5.编译时刻加载类是静态加载类,运行时刻加载类是动态加载类。

6.new创建对象是静态加载类,在编译时刻就需要加载所有的可能使用到的类。

通过动态加载类,可以解决该问题。

7.

Class c1 = int.class;
Class c2 = double.class;
Class c3 = Double.class;
Class c4 = void.class;
System.out.println(c1.getName());
System.out.printlin(c2.getSimpleName());//不包含包名的类的名称

c2与c3不同。

8.基本的数据类型、 void关键字,都存在类类型。

9.

Class c = obj.getClass();
Method[] ms = c.getMethods();
for(int i=0;i<ms.length;i++){
  Class returnType = ms[i].getReturnType();//得到方法的返回值类型的类类型
  System.out.print(returnType.getName()+" "); 
  System.out.print(ms[i].getName()+"(");//得到方法的名称
  //获取参数类型——>得到的是参数列表类型的类类型
  Class[] paramTypes = ms[i].getParameterTypes();
  for(Class class1 : paramTypes){
    System.out.print(class1.getName()+",");
  }
  System.out.println(")");
}

Method类是方法对象,一个成员方法就是一个Method对象。getMethods()方法获取所有public的函数,包括父类继承而来的;而而getDeclaredMethods()获取的是所有该类自己声明的方法,不问访问权限。

10.

Field[] fs = c.getDeclaredFields();
for(Field field : fs){
    //得到成员变量的类型的类类型
    class fieldType = field.getType();
    String typeNmae = fieldType.getName();
    //得到成员变量的名称
    String fieldName = field.getName();
    System.out.println(typeNmae+" "+fieldName);
}

成员变量也是对象,Field类封装了关于成员变量的操作。getFields()方法可以获取所有public成员变量的信息,而getDeclaredFields()方法获取的是所有该类自己声明的成员变量的信息。

11.

Constructor[] cs = c.getDeclaredConstructors();

构造函数也是对象,java.lang.Constructor中封装了构造函数的信息。getConstructors()获取所有的public的构造函数,getDeclaredConstructors()得到所有的(自己声明的)构造函数(构造函数都需要自己声明)。

12.反射的操作都是编译之后的操作。

ArrayList list = new ArrayList();
ArrayList<String> list1 = new ArrayList<String>();
Class c1 = list.getClass();
Class c2 = list1.getClass();
System.out.println(c1 == c2);

c1==c2,结果返回true.说明,编译之后集合的泛型是去泛型化的。java中,集合的泛型是防止错误输入的,只在编译阶段有效,绕过编译就无效了。

验证:我们可以通过方法的反射来操作,绕过编译。

Method m = c2.getMethod("add",Object.class);
m.invoke(list1,100);//绕过编译操作,就绕过了泛型
System.out.println(list1.size());