欢迎使用CSDN-markdown编辑器

来源:互联网 发布:多益网络加班严重吗 编辑:程序博客网 时间:2024/06/02 03:49

反射

Class类是一个实例对象,任何一个Class类的实例对象都有三种表达方式
Foo foo1 = new Foo();//foo1就表示出来了
第一种表达方式–>实际在告诉我们任何一个类都有一个隐含的静态成员变量class
Class c1 = Foo.class;
第二种表达方式 已经知道该类的对象通过getClass方法
Class c2 = foo1.getClass();
官网的说法是c1,c2表示了Foo类的类类型(class type) (foo1是父类的对象,c1,c2是foo1的类类型)
第三种表达方式
Class c3 = null;
c3 = Class.forName(“包名.类”);
我们完全可以通过类的类型创建该类的对象实例–通过以上三种方式创建Foo的类类型
Foo foo= (Foo)c1.newInstance(); (创建实例对象,也就是new)

Class.forName(“类的名称”)
静态加载类(程序启动的时候加载所有可能使用到的类)
动态加载类(程序运行后,用到哪一个类,加载哪一个类,不调用的不影响。)[也就是建立一个(接口)标准,去实现标准]
- 不仅表示了类的类类型,还表示了动态加载类
- 编译时候加载类是静态加载类、运行时刻加载类是动态加载类

Method类,方法对象,getMethods()方法获取的是所有public的函数,包括了父类继承来的。
getDeclaredMethods()获取所有自己声明的方法,不问访问权限。
Method[] ms = c1.getMethods();
ms[i].getReturnType()[得到方法的返回值类型的类类型]
ms[i].getName()[得到方法的名字]
ms[i].getParameterTypes()[获取参数类型,得到的是一个参数的类类型数组]

要获取一个方法就是获取类的信息,获取类的信息首先要获取类的类类型。
A a1 = new A();
Class c = a1.getClass();
//获取方法名称和参数列表来决定
//getMethod获取的是public的方法
//getDelcaredMethod自己声明的方法
Method m = c.getMethod(方法的名称,参数类类型数组)[第二个参数可以写成数组也可以直接写,隔开]
//方法的反射操作是用m对象来进行方法的调用,与平时我们调方法完全相同
//方法如果没有返回值返回null,有返回值返回具体的返回值
m.invoke(a1,参数类类型数组);

成员变量也是对象
java.lang.reflect.Field(Field类封装了关于成员变量的操作)
getFields()方法获取的是所有的public的成员变量的信息
getDeclaredFields获取的是该类自己声明的成员变量的信息。
Field[] fs = c.getDeclaredFields();
fs.getType()[获取成员变量的类型的类类型]

构造函数也是对象
java.lang.Constructor中封装了构造函数的信息
getConstructors获取所有的public的构造函数
getDeclaredConstructors[得到所有的构造函数]
Constructor[] cs = c.getDeclaredConstructors();
cs.getName();
cs.getParameterTypes();[获取构造函数的参数列表,得到的是参数列表的类类型数组]

泛型的本质
ArrayList list = new ArrayList();
ArrayList list1 = new ArrayList();
Class c1 = list.getClass();
Class c2 = list1.getClass();
System.out.println(c1 == c2);

//c1==c2返回true说明编译之后集合的泛型是去泛型化的
//java中集合的泛型,是放置错误输入的,只在编译阶段有效,绕过编译就无效了。
//验证:我们可以通过方法的反射来操作,绕过编译
Method m = c2.getMethod(方法名称,Object.class);
m.invoke(list1,100);//绕过编译操作就绕过了泛型,将int类型存入到String泛型的集合中
//这样就不能使用for遍历了,会出现类型转换异常,只能直接打印整个集合

总结:首先获取一个类的类类型,再通过类类型获取该类的信息(方法,成员变量,构造函数等等)。

原创粉丝点击