概要解释
github地址:
目录图
学习地址:MOOC
反射的操作会绕过编译。
Java里:除了基本数据类型和静态成员两部分不能当成对象外,其余一切都可以看成对象。
class作为对象是java.lang.Class类的对象实例。
class构造函数
/*Class类中默认的构造函数
*Private class():只能被JVM创建,外界不能显示创建或者调用。
* Private constructor.
*Only the Java Virtual Machine creates Class objects.
* ClassLoader归JVM部分
*/
private Class(ClassLoader loader) {
// Initialize final field for classLoader. The initialization value of non-null
// prevents future JIT optimizations from assuming this final field is null.
classLoader = loader;
}
具体应用
Class类的反射使用
3种获取类类型的方法
1.类名.class
2.对象名.getClass()
3.Class.forName(" ")
Class c1=Foo.class;
Class c2=foo01.getClass();
Class c3=null;
//写对象地址要具体到类名。
c3=Class.forName("reflect.base.Foo");
创建实例的方法
创建类的实例的方法:
1.通过类对象反射创建,创建后需要注意返回类型可能需要类型转换。
try {
Foo foo=(Foo)c1.newInstance();
foo.print();
}
catch (InstantiationException e) {
e.printStackTrace();
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
Java类加载机制
编译时刻加载类是静态加载,运行时刻加载类是动态加载。
New创建对象是静态加载类,而静态加载就意味着编译时刻就会加载所有可能用到的类,只要有一个没有就回报错。
动态加载:加载当前需要的类就可以,对于编译指令没涉及到的类不会管。
获取方法
java.lang.reflect.Method
基本类型、封装类、关键字都可以.class获得
获取类->得到返回类型的类类型->得到返回值类型-> 得到方法的名称->获取参数列表的类类
/**
* getMethods()获取的是所有的public类型的函数
* getDeclaredMethods()获取的是该类自己声明的方法。
*/
//获取类
Class c=obj.getClass();
System.out.println("类名称是" + c.getName());
Method[] ms=c.getMethods();
Method[] mes=c.getDeclaredMethods();
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[] paramTpres=ms[i].getParameterTypes();
//获取参数列表的类类型
for (Class class1:paramTpres
) {
System.out.print(","+class1.getSimpleName().toString());
}
System.out.println(")");
}
获取成员变量信息
java.lang.reflect.Filed
/**
* getFields()获取的是所有的public成员变量的的信息
* getDeclaredFields()获取的是该类自己声明的成员变量的信息。
*/
//获取类
Class c=obj.getClass();
System.out.println("类名称是" + c.getName());
Field[] fs=c.getFields();
Field[] fis=c.getDeclaredFields();
for (Field field:fs
) { //得到成员变量的类型的类类型
Class typeName=field.getType();
String fieldName=field.getName();
System.out.println(typeName + ":" + fieldName);
获取构造方法
java.lang.reflect.Constructor
获得一个类的类类型->获得一个类的信息
Class c=obj.getClass();
System.out.println("类名称是" + c.getName());
//构造函数也是对象
//getConstructors得到所有的构造函数
//getConstructors得到自己定义的的构造函数
Constructor[] cs=c.getConstructors();
Constructor[] cos=c.getDeclaredConstructors();
for (Constructor con:cs
) {
System.out.print(con.getName() + " (");
Class[] paraTypes=con.getParameterTypes();
for (Class cla:paraTypes
) {
System.out.print(","+cla.getSimpleName());
}
System.out.println(")");
}
方法的反射操作
获取方法的对象->用方法对象 反射操作
method.invoke(对象名,参数列表)//方法的名称和参数列表结合才能唯一决定某个方法。
class字节码是编译之后的,反射是编译之后的操作。
集合的范型是防止错误输入的,旨在编译阶段提示,但是集合本身是当成Object(设计的目的就是为了可以存储不同的类型)处理的。所以编译后,集合的范型是去范型化的。