类反射,代理

Class文件加载流程

类的加载条件:

当创建一个类的实例时,如 通过new创建对象,或者通过反射、克隆、反序列化

调用类方法时,即使用了字节码的invokestatic指令

当使用类或接口的类字段(除final常量外),比如使用了getstatic或pushstatic指令

当使用了java.lang.reflect包中的方法反射类的方法时

当初始化子类时,要求先初始化父类

作为启动虚拟机,含有main方法的哪个类

类加载器

类加载器(CLassLoader)用于加载类,在Java中主要有以下四种类加载器:

Bootstrap ClassLoader:此加载器采用C++编写,一般开发中是看不到的,加载系统核心类,如String类;

Extension ClassLoader:用来进行扩展类的加载,一般对应的是jrelibext目录中的类;

AppClassLoader:加载classpath指定的类,即加载用户类,也就是应用程序的类。

自定义类加载器

Class类型获取

public class Class_test {
    public static void main(String[] args) throws ClassNotFoundException {
        1
     Class
<Class_test> class_testClass = Class_test.class; System.out.println(class_testClass); //class com.zym.com.zym.Class_test      2 Class_test class_test = new Class_test(); Class aClass = class_test.getClass(); System.out.println(aClass); //class com.zym.com.zym.Class_test      3 Class aClass1 = Class.forName("com.zym.com.zym.Class_test"); System.out.println(aClass1); //class com.zym.com.zym.Class_test } }

 反射

public class fanshe {
    public static void main(String[] args) {
        //获得一个类
        Class<Student1> cls = Student1.class;

        //获取类所在的包
        Package apackage = cls.getPackage();
        System.out.println(apackage);

        //获得属性(公开)
        System.out.println("获得属性(公开)");
        Field[] attr_Student1 = cls.getFields();
        for (Field s : attr_Student1
        ) {
            System.out.println(s);
        }

        //获得属性(所有)
        System.out.println("------------------");
        System.out.println("获得属性(所有)");
        Field[] fileds_all_stu1 = cls.getDeclaredFields();
        for (Field f : fileds_all_stu1
        ) {
            System.out.println(f);
        }

        //获得构造方法(公开的),一般加Declared的都是所有
        System.out.println("-----------");
        Constructor<?>[] constructors = cls.getConstructors();
        for (Constructor con:constructors
             ) {
            System.out.println(con);
        }

        //获得普通的犯法,公开的方法,包括继承的方法
        System.out.println("-----------");
        Method[] methods = cls.getMethods();
        for (Method m:methods
             ) {
//            System.out.println(m);
        }

        //获得普通方法,所有本类的所有方法,不包括继承方法
        System.out.println("-----------");
        Method[] declaredMethods = cls.getDeclaredMethods();
        for (Method s : declaredMethods
             ) {
            System.out.println(s);
        }


    }


}

执行类中的方法,普通方法,构造方法

public class TestPropertyDescriptor {
     public static void main(String[] args) {
          Person person = new Person();
          person.setName("zhangsan");
          person.setAge(18);
          getFiled(person, "name");//结果输出 zhangsan
     }
     
     // 通过反射得到name 
     // 通过得到属性的get方法(pd.getReadMethod())再调用invole方法取出对应的属性值
     // 调用set方法()
     private static void getField(Object object, String field) {
          Class<? extends Object> clazz  = object.getClass();
          PropertyDescriptor pd = null;
          Method getMethod = null;
          Method setMethod = null;
          try {
              pd = new PropertyDescriptor(field, clazz);
              if (null != pd) {
                   // 获取field属性的get方法
                   getMethod = pd.getReadMethod();
                   Object getInvoke = getMethod.invoke(object);
                   // 获取field属性的set方法
                   setMethod= pd.getWriteMethod();
                   Object setInvoke = setMethod.invoke(object,"123");
                   System.out.println(setInvoke+ getInvoke);
              }
          } catch (Exception e) {
              e.printStackTrace();
          }
          
     }
}



public static void main(String[] args) throws Exception {
        //给对象赋值
        /*Person p = new Person();
        p.setAge(20);
        p.setAddress("北京");
        p.setName("张三");*/
        //获得Person的Class类型 
        Class<Person> cls = Person.class;
        //实例化Person
        /*Person p = cls.newInstance();//通过Person无参构造方法实例化
        p.setAge(20);
        p.setAddress("北京");
        p.setName("张三");
        System.out.println(p);*/
        Constructor<Person> con = cls.getConstructor(String.class,int.class,String.class);
        Person p=con.newInstance("张三",23,"昌平");
        //获得set方法
        Field field = cls.getDeclaredField("age");
//        System.out.println(field.getName());
        String mname="set"+field.getName().substring(0, 1).toUpperCase()+field.getName().substring(1);
        System.out.println(mname);
        Method m = cls.getMethod(mname, int.class);
        //执行方法
         m.invoke(p,21);
         System.out.println(p);
         
         //调用show
         Method show = cls.getMethod("show", String.class);
         //    obj 实例对象,args 参数
         show.invoke(p, "测试");

    }

反射缺点

破坏了类的封装;

平时开发不会使用反射机制!!!

设计模式

静态代理

一个接口一个功能,也可以在代理类中写功能

对其他对象提供一种代理以控制对这个对象的访问。

对已经存在的类,添加功能,不能修改原有类的任何功能!!!

public class compute implements PublicObject {


    @Override
    public void Info(String name, double price) {
        System.out.println("电脑名称:"+name+"价格:"+price);
    }


}
compute
public class proxy implements PublicObject{
    public PublicObject po;


    public proxy(PublicObject po) {
        this.po = po;
    }


    @Override
    public void Info(String name, double price) {
        po.Info(name,price);

    }

    public void gift(){
        System.out.println("反现金");
    }


}
代理类
public interface PublicObject{
    public void Info(String name,double price);


}
继承的接口
public class proxy_test {
    public static void main(String[] args) {
        compute c = new compute();
        proxy p = new proxy(c);

        p.Info("zzzz", 123);
        p.gift();
    }

}
测试类

 动态代理

之前曾为读者讲解过代理机制的操作,但是之前所讲解的代理设计,属于静态代理,因为每一个代理类只能为一个接口服务,这样一来程序开发中必然会产生过多的代理了,最好的做法是可以通过一个代理类完成全部的代理功能,那么此时就必须使用动态代理完成。

在Java中要想实现动态代理机制,则需要java.lang.reflect.InvocationHandler接口和java.lang.reflect.Proxy类的支持。

public class MyProxy implements InvocationHandler{//动态代理
    private Object obj;
    
    //绑定的对象
    public Object bind(Object o){
        this.obj=o;
//        ClassLoader loader:类加载器 
//        Class<?>[] interfaces:得到全部的接口 
//        InvocationHandler h:得到InvocationHandler接口的子类实例 

        return Proxy.newProxyInstance(o.getClass().getClassLoader(), o.getClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//        System.out.println("参数:"+Arrays.toString(args));
//        System.out.println(method.getName());
        return method.invoke(obj, args); //执行目标对象的方法
    }
    
}
代理类
//目标对象
public class Computer implements PublicObj {

    @Override
    public void Info(String name, double price) {
        System.out.println(name+"系列电脑!"+price);
    }

}
compute
//抽象对象
public interface PublicObj {
    //电脑系列
    public void Info(String name,double price);

}
抽象接口
public class Test {

    public static void main(String[] args) {
        MyProxy handler = new MyProxy();
        PublicObj po =new Computer();//真实目标对象
        PublicObj o = (PublicObj) handler.bind(po);
         o.Info("IBM", 9999.99);

    }

}
测试类
原文地址:https://www.cnblogs.com/taozizainali/p/10883317.html