类的加载过程:
程序经过java.exe命令以后,会生成一个或多个字节码文件(.class结尾)接着我们使用java.exe命令对某个字节码文件进行解释运行,相当于将某个字节码文件加载到内存当中,此过程就被称为类的加载。
加载到内存中的类,我们称之为运行时类,此运行时类,就作为Class的一个实例
使用反射,创建对象,调用方法,获取属性
获取运行时类
方式 1:Class clazz=Student.class; // Class<Student> clazz=Student.class;
方式 2:Class clazz=Student.getClass;
方式 3:Class clazz=forName("com.zx.java.Student");
方式 4:ClassLoader cl = Student.class.getClassLoader();
Class clazz=cl.loadClass("com.zx.java.Student");
创建对象
方式 1:公共 无参构造器
Student student=(Student)clazz.newInstance();
方式 2:私有 有参构造器
Constructor constructor = clazz.getDeclaredConstructor(String.class,String.class); //获取指定构造方法
constructor.setAccessible(true); //设置为true可以访问类的私有方法
Student student=(Student)constructor.newInstance("solo","男"); //创建对象
调用方法
方式 1:公共 无参方法
Method show = clazz.getDeclaredMethod("show");
show.invoke(student);
方式 2:私有 有参方法
Method message = clazz.getDeclaredMethod("message",String.class);
message.setAccessible(true);
message.invoke(student,"lost");
方式 3:公共 静态无参方法
Method parse = clazz.getDeclaredMethod("parse");
parse.invoke(clazz);
操作属性
方式 1:公共 属性
Field sex = clazz.getDeclaredField("sex");
sex.set(student,"男 or 女");
sex.get(student);
方式 2:私有 属性
Field name = clazz.getDeclaredField("name");
name.setAccessible(true);
name.set(student,"solo");
name.get(student);
获取运行时类的详细结构
获取属性:
获取当前运行时类和父类中所有权限为public的属性
Field[] fields1 = clazz.getFields();
获取当前运行时类中所有权限的属性
Field[] fields2 = clazz.getDeclaredFields();
field.getName(); 获取属性名称
Modifier.toString(fields.getModifiers()); 获取权限
获取方法:
获取当前运行时类和父类中所有权限为public的方法
Method[] Method1 = clazz.getMethods();
获取当前运行时类中所有权限的方法
Method[] Method2 = clazz.getDeclaredMethods();
Modifier.toString(method.getModifiers()); 获取权限
Method.getReturnType(); 获取返回类型
Method.getName(); 获取方法名称
Method.getParameterTypes(); 获取参数列表
Method.getExceptionTypes(); 获取异常列表
Method.getDeclaredAnnotations(); 获取注解
获取构造器
获取当前运行时类和父类中所有权限为public的方法
Constructor[] cs = clazz.getConstructors();
获取当前运行时类中所有权限的方法
Constructor[] cs = clazz.getDeclaredConstructors();
获取父类与泛型
获取父类
Type gs= clazz.getGenericSuperclass();
获取泛型
ParameterizedType pt=(ParameterizedType)gs;
Type[] ta = pt.getActualTypeArguments();
ta[0].getTypeName();
获取接口,所在的包,注解
Class[] interfaces = clazz.getInterfaces();
Package Package = clazz.getPackage();
获取注解
Annotation[] annotations = clazz.getAnnotations();
静态代理
public class ProxyTest{
public static void main(String[] args){
NikeClothes nick = new NikeClothes();
ProxyClothesFactory pcf = new ProxyClothesFactory(nick);
pcf.produce();
}
}
//接口
interface Clothes{
public void produce();
}
//代理类
class ProxyClothesFactory implements Clothes{
Clothes clothes;
public ProxyClothesFactory(Clothes clothes){
this.clothes=clothes;
}
@Override
public void produce() {
System.out.println("生产前的准备.....");
clothes.produce();
System.out.println("生产结束.....");
}
}
//被代理类
class NikeClothes implements Clothes{
@Override
public void produce() {
System.out.println("正在生产......");
}
}
动态代理
public class ProxyTest {
public static void main(String[] args){
SuperMan sm=new SuperMan();
Human human=(Human)ProxyFactory.newInstance(sm);
int height=human.getHeight();
String linkFood=human.linkFood("肉");
System.out.println(height);
System.out.println(linkFood);
}
}
interface Human{
int getHeight();
String linkFood(String food);
}
//代理类
class ProxyFactory{
public static Object newInstance(Object obj){
MyInvocationHandler mih=new MyInvocationHandler();
mih.bin(obj);
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),mih);
}
}
class MyInvocationHandler implements InvocationHandler {
private Object obj;
public void bin(Object obj){
this.obj=obj;
}
//方法的增强
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("方法执行前的准备工作,开始");
Object returnValue= method.invoke(obj,args);
System.out.println("方法结束前的收尾工作,结束");
return returnValue;
}
}
//被代理类
class SuperMan implements Human{
@Override
public int getHeight() {
return 100;
}
@Override
public String linkFood(String food) {
return food;
}
}
------------------END------------------