• 类反射,代理


    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);
    
        }
    
    }
    测试类
  • 相关阅读:
    焦点轮播图——myfocus焦点图库
    7个你可能不认识的CSS单位:rem vh vw vmin vmax ex ch
    FullPage.js全屏滚动插件的配置项、方法和回调函数
    background不能填充margin的问题
    LESS CSS 框架简介
    shell命令合集
    css布局模型之绝对定位与相对定位
    购物网站中,选择不同颜色和尺寸时,相应地方的文字也跟着改变
    jqzoom基于jQuery的图片放大镜
    c# DataTable 导出csv文件
  • 原文地址:https://www.cnblogs.com/taozizainali/p/10883317.html
Copyright © 2020-2023  润新知