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());
浙公网安备 33010602011771号