1、 .class的代码会加载到JVM区域,类的信息进入内存
2、每一个类都会生成一个与之对应的Class类的对象,存储了类的所有信息
3、触发类加载的时机:(类加载只有一次)
a、创建对象的时候
b、调用静态属性、静态方法的时候
c、创建子类的时候
1、Class对象:
一个类会有一个与之对应的Class实例,在类加载的时候生成对象,代表该类的信息
2、获取一个Class实例的方法:
a)、通过对象获得:
Class clazz1 = 对象.getClass();
Class clazz2 = 对象.getClass();
注:上述两个对象为同一个对象
b)、通过.class获得:
Class clazz3 = 类名.class;
不会触发类加载
c)、通过Class.forName()获得:
Class clazz4 = Class.forName(“类的全路径”);
d)、clazz1 == clazz2 == clazz3 ==clazz4
反射概念:
反射机制是在运行状态中:
a)、对于任意一个类,都能够知道这个类的所有属性和方法;
b)、对于任意一个对象,都能够调用它的任意一个方法和属性
反射提供的功能:
a)、在运行时判断任意一个对象所属的类
b)、在运行时构造任意一个类的对象
c)、在运行时判断任意一个类所具有的成员变量和方法
d)、在运行时调用任意一个对象的方法
e)、生成动态代理
反射常用的方法:
首先先获取一个Class实例:
Class clazz = null;
try {
clazz = Class.forName("包名.类名");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
.获取所有的公共 方法(本类以及父类、接口中的所方法,符合访问修饰符规律,即private中的无法获取)
Method[] methods = clazz.getMethods();
获取当前类的所有方法(不包括父类,忽略访问修饰符的限制):
Method[] declaredMethods = c1.getDeclaredMethods();
获取当前类的特定方法:
Method method = clazz.getDeclaredMethod("方法名", 参数类型无参数则为null);
获取构造方法:
Constructor[] constructors = clazz.getConstructors();
获取指定的公共构造方法:该方法的参数为构造方法参数的类型,可以有多个
Constructor constructor = clazz.getConstructor(int.class);
获取指定的私有构造方法:该方法的参数为构造方法参数的类型,可以有多个
Constructor constructor2 = clazz.getDeclaredConstructor(String.class);
调用获取到的方法:
method为获取到的方法,obj为调用方法的对象,value为方法参数的值,无参数则为null
method.invoke(obj,value);
获取类的所有的公共属性(规则符合上面获取所有公共方法):
Field[] fields = clazz.getFields();
获取当前类的所有属性(不包括父类,忽略访问修饰符限制):
Field[] declaredFields = clazz.getDeclaredFields();
获取当前类的特定属性:
Field field = c1.getDeclaredField("属性名");
操作获取到的属性: field为获取到的属性名,obj为要操作属性的对象,value为属性的值
field.set(obj,value);
获取所有的接口:
Class[] interfaces = clazz.getInterfaces();
获取所有的父类:
Class supclass = clazz.getSuperclass();
获取当前类(接口)的对象(实例):
Object instance = clazz.newInstance();
在调用方法或操作属性时若方法或属性为private的时候,则在操作之前需要修改访问权限:
method.setAccessible(true);//私有方法调用前使用该方法
field.setAccessible(true);//私有属性操作前使用该方法