zoukankan      html  css  js  c++  java
  • 24.类的加载机制和反射.md

    1类的加载连接和初始化

    1.1类的加载过程

    类的加载过程简单为分为三步:加载->连接->初始化


    1.2类的加载器

    1.2.1类的加载机制

    • 全盘加载:
      使用一个类负责加载一个Class文件,该Class依赖和负责的Class都由这个类加载器负责加载
    • 父类加载:
      先让这个类的父类加载器加载这个类,只有当这个父加载器无法加载时候,才从自己的类路径中加载该类
    • 缓存机制:
      所有被加载过的类都会被缓存,当程序需要某个类的时候,类加载器先从缓冲区寻找这个类,只有当这个类在缓存区不存在时候,才会读取对应的二进制文件,转换为Class对象,所以每次修改了Class后,需要重启JVM才能生效

    加载器的继承的顺序,其中自定义的加载器通过继承ClassLoader来实现:

    依照这个顺序,可以得到一个类加载的顺序


    1.通过反射获得类的信息

    package com.liyue.studycode.classreflect;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
     
    @Retention(value = RetentionPolicy.RUNTIME)
    @interface Anno{}
    @SuppressWarnings(value = "unused")
    public class BaseClass {
        //declare a private constructor.
        private BaseClass(){};
         
        //decalre a public constructor
        public BaseClass(int id){
            System.out.println("excute a public constructor");
        }
         
        //delcare a void function 
        public void fun(){
            System.out.println("excute a void function");
        };
         
        //declare a function with paramter
        public void test(String name){
            System.out.println("excute a function with paramter: " + name);
        }  
         
    }
    
    package com.liyue.studycode.classreflect;
     
    import java.lang.annotation.Annotation;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Method;
    import java.util.Arrays;
     
    public class RefectMain {
     
        public static void main(String[] args) throws NoSuchMethodException, SecurityException {
            //get class's object
            Class<BaseClass> cl = BaseClass.class;
             
            //get all public constructor
            Constructor[] constructor = cl.getDeclaredConstructors();
            System.out.println("All of BaseClass's constuctor:");
            for(Constructor c : constructor){
                System.out.println(c);
            }
             
            //get all public method
            Method[] method = cl.getMethods();
            System.out.println("All of BaseClass's constuctor:");
            for(Method m : method){
                System.out.println(m);
            }
             
            //get designated method
            System.out.println("BaseClass's function with parameter named"
                    + "test" + cl.getMethod("test", String.class) );
             
            //get all annotation of BaseClass
            Annotation[] an = cl.getAnnotations();
            System.out.println("All annotation of BaseClass:");
            for(Annotation a : an){
                System.out.println(a);
            }
             
            //get @SuppressWarnings
            System.out.println("BaseClass's SuppressWarnings:"
                    + Arrays.toString(cl.getAnnotationsByType
                            (SuppressWarnings.class)));
             
            //get package
            System.out.println("BaseClass's package:"
                    + cl.getPackage());
        }
     
    }
    

    2.Java 8新增的方法参数反射

    如果将上例BaseClass.test方法改造一下:

    public void test(String name, int num){
            System.out.println("excute a function with paramter: " + name);
        } 
    

    那么可以这么获取参数

    Class<BaseClass> cl = BaseClass.class;
            Method m = cl.getMethod("test", String.class, int.class);     
            Parameter[] ps = m.getParameters();
            System.out.println(m.getParameterCount());
            for(Parameter p : ps){
                System.out.println(p.getName());
                System.out.println(p.getType());
                System.out.println(p.getParameterizedType());        
            }
    

    3.通过反射操作对象
    3.1创建对象
    3.1.1使用newInstance方法

    package com.liyue.studycode.objectfactory;
     
    import java.io.FileInputStream;
    import java.util.HashMap;
    import java.util.Properties;
     
     
    public class ObjectFactory {
        //declare a map to save object
        private HashMap<String, Object> objectPool = new HashMap<>();
         
        //declare function to new class,return object by class name
        private Object createObject(String targetClassNmae)
                throws Exception{
            Class<?> cl = Class.forName(targetClassNmae);
            return cl.newInstance();
        }
         
        //read property file
        public void initObjectPool(String fileName) 
                throws Exception{
            Properties pRead = new Properties();
            pRead.load(new FileInputStream(fileName));
            for(String name : pRead.stringPropertyNames()){
                objectPool.put(name, createObject(pRead.getProperty(name)));
            }      
        }
         
        //return object of Map
        public Object getObject(String name){
            return objectPool.get(name);
        }  
    }
    

    定义一个属性文件,保存需要读取的信息

    a = java.util.Date
    b = javax.swing.JFrame
    
    package com.liyue.studycode.objectfactory;
     
    public class ObjectFactoryPrint {
     
        public static void main(String[] args) {
            ObjectFactory of = new ObjectFactory();
            try {
                of.initObjectPool("Properties//myclassrelectconfig.ini");
                System.out.println(of.getObject("a"));
                System.out.println(of.getObject("b"));
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    

    3.1.2使用Constructor创建

    try {
        Class<?> cl = Class.forName("javax.swing.JFrame");
        Constructor c = cl.getConstructor(String.class);
        Object obj = c.newInstance("哈哈");
        System.out.println(obj);
         
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    

    3.2调用方法

    package com.liyue.studycode.objectfactory;
     
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Method;
     
    public class ObjectFactoryPrint {
     
        public static void main(String[] args) throws Exception{
            try {
                //call method forName
                Class<?> cl = Class.forName("javax.swing.JFrame");
                //get constructor
                Constructor c = cl.getConstructor(String.class);
                //get instance of JFrame
                Object obj = c.newInstance("");
                //get method setTitle
                Method md = cl.getMethod("setTitle", String.class);
                //call invoke
                md.invoke(obj, "哈哈");
                System.out.println(obj);
                 
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    

    3.3访问成员变量

    package com.liyue.studycode.fieldreflect;
     
    import java.lang.reflect.Field;
     
    public class FieldReflectPrint {
     
        public static void main(String[] args) 
                throws Exception{
            Emploee e = new Emploee();
            Class<?> cl = e.getClass();
            //getDeclaredField get field of the class
            /*get name*/
            Field nameField = cl.getDeclaredField("name");
            //Set the accessible flag for this object
            nameField.setAccessible(true);
            //set new value
            nameField.set(e, "张三");
            /*get age*/
            Field agefield = cl.getDeclaredField("age");
            //Set the accessible flag for this object
            agefield.setAccessible(true);
            //set new value
            agefield.set(e, 29);
             
            System.out.println(e);
             
        }
    }
    

    3.4获取数组

    4.使用反射生成JDK动态代理

    4.1创建动态代理

    package com.liyue.study.dynamicobject;
     
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
     
    public class MyInvokationHandler implements InvocationHandler {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if(args != null){
                System.out.println("下面是执行该方法时候传入的实参:");
                for (Object v : args) {
                    System.out.println(v);
                }
            }
            else{
                System.out.println("调用该方法没有实参。");
            }
            return null;
        }
     
    }
    
    package com.liyue.study.dynamicobject;
     
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Proxy;
     
    public class DynamicObjectPrint {
        public static void main(String[] args) throws Exception{
            InvocationHandler handler = new MyInvokationHandler();
            //使用InvocationHandler生成一个动态对象
            Person p = (Person)Proxy.newProxyInstance(Person.class.getClassLoader()
                    , new Class[]{Person.class}
                    , handler);
            p.walk();
            p.sayHello("李四");
        }
    }
    

    4.2动态代理和AOP

    package com.liyue.studycode.aop;
     
    public interface Bird {
        //definition two abstract function
        void info();
        void fly();
    }
    
    package com.liyue.studycode.aop;
     
    public class Duck implements Bird {
     
        @Override
        public void info() {
            // TODO Auto-generated method stub
            System.out.println("I am a duck!");
        }
     
        @Override
        public void fly() {
            // TODO Auto-generated method stub
            System.out.println("I can fly!");
        }
    }
    
    package com.liyue.studycode.aop;
     
    public class BirdUtil {
        //This is the first simulation function 
        public void fun1(){
            System.out.println("This is birdutil function 1!");
        }
        //This is the second simulation function 
        public void fun2(){
            System.out.println("This is birdutil function 2!");
        }
    }
    
    package com.liyue.studycode.aop;
     
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
     
    public class MyInvocationHandler implements InvocationHandler {
        //The object need to agented
        private Object target;
        //setter
        public void setTarget(Object target) {
            this.target = target;
        }
     
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) 
                throws Exception {
            BirdUtil bu = new BirdUtil();
            //simulate the first function
            bu.fun1();
            //use target to excute method
            Object result = method.invoke(target, args);
            //simulate the second function
            bu.fun2();
             
            return result;
        }
     
    }
    
    package com.liyue.studycode.aop;
     
    import java.lang.reflect.Proxy;
     
    import com.liyue.studycode.aop.MyInvocationHandler;
     
    public class MyProxy {
        public static Object getProxy(Object target) 
                throws Exception{
            //create a MyInvocationHandler
            MyInvocationHandler mih = new MyInvocationHandler();
            //set target to mih
            mih.setTarget(target);
             
            return Proxy.newProxyInstance(target.getClass().getClassLoader()
                    , target.getClass().getInterfaces()
                    , mih);
        }
    }
    

    package com.liyue.studycode.aop;
     
    import com.liyue.study.dynamicobject.MyProxy;
     
    public class AopPrint {
     
        public static void main(String[] args) 
                throws Exception {
            //create a object of Duck
            Bird target = new Duck();
            Bird b = (Bird)MyProxy.getProxy(target);
            b.info();
            b.fly();
        }
     
    }
    

    有参构造的调用
    有一个带参构造:

    package pers.liyue.generic.test;
     
    public class ReflectTest {
        public int num = 0;
        public double size = 0.00;
        private float bignum = 0;
         
        public ReflectTest(){
            System.out.println("Create class!");
        }
         
        public ReflectTest(int numb){
            System.out.println("Create class with args!" + numb);
        }
    }
    

    调用时候不能用默认的newInstance

    public static void main(String[] args) throws Exception {
            // TODO Auto-generated method stub
            ReflectTest rt = new ReflectTest();
            rt.Fun1();
            //无参构造调用
            Class c = Class.forName("pers.liyue.generic.test.ReflectTest");
            ReflectTest o = (ReflectTest)c.newInstance();
            //有参构造调用
            Constructor ccc = c.getConstructor(new Class[]{int.class});
            ReflectTest b = (ReflectTest)ccc.newInstance(new Object[]{1});
        }
    
  • 相关阅读:
    离散化(AcWing.802)
    Hexo+coding实现自动化部署
    八、django学习之分组查询、F查询和Q查询
    七、django学习之聚合函数
    六、Django学习之基于下划线的跨表查询
    五、Django学习之基于对象的跨表查询
    四、Django学习之关系表介绍及使用
    三、Django学习之单表查询接口
    二、Django学习之增删改查
    Spacy模块:自然语言处理一站式工具
  • 原文地址:https://www.cnblogs.com/bugstar/p/8492835.html
Copyright © 2011-2022 走看看