• java 反射,类的加载过程以及Classloader类加载器


    首先自定义一个类Person

    package reflection;
    
    public class Person {
        
        private String name;
        public int age;
        
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        @Override
        public String toString() {
            return "Person [name=" + name + ", age=" + age + "]";
        }
        public Person(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
        public Person() {
            super();
        }
        
        public Person(String name) {
            super();
            this.name = name;
        }
        public void show() {
            System.out.println("我是一个人");
        }
        private String showNation(String nation){
            System.out.println("我的国籍是"+nation);
            return nation;
        }
    }
    View Code

    然后是反射的一些操作

    package reflection;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.Properties;
    
    import org.junit.jupiter.api.Test;
    
    
    public class ReflectionTest {
        
        @Test
        public void test1() throws Exception {
            Person p1 = new Person("Tom",12);
            
            //1.通过反射,创建Person类的对象
            Class clazz = Person.class;
            Constructor cons = clazz.getDeclaredConstructor(String.class,int.class);
            
            Object obj = cons.newInstance("Tom",12);
            Person p = (Person)obj;
            System.out.println(p.toString());
        
            //2.通过反射,调用对象指定的属性
            Field age = clazz.getDeclaredField("age");
            age.set(p, 10);
            System.out.println(p.toString());
        
            //3.通过反射,调用方法
            Method show = clazz.getDeclaredMethod("show");
            show.invoke(p);
            
            System.out.println("**********************************************************");
        }
        
        /*
         * 反射调用私有方法和属性
         * */
        @Test
        public void test2() throws Exception{
            try {
                //通过反射调用私有的方法和属性
                Class clazz = Person.class;
                //1.调用私有构造器
                Constructor cons1 = clazz.getDeclaredConstructor(String.class);
                cons1.setAccessible(true);
                Person person = (Person)cons1.newInstance("zsben");
                System.out.println(person);
                        
                //2.调用私有属性
                Field name = clazz.getDeclaredField("name");
                name.setAccessible(true);
                name.set(person, "Lilei");
                System.out.println(person);
                        
                //3.调用私有方法
                Method showNation =  clazz.getDeclaredMethod("showNation",String.class);
                showNation.setAccessible(true);
                showNation.invoke(person, "中国");
                
                //4.获得私有方法的返回值
                String string = (String)showNation.invoke(person, "中国");
                System.out.println(string);
            } catch (Exception e) {
            
                e.printStackTrace();
            }
        }
        
        /*    关于Class类的理解
         *         1.类的加载过程:使用java.exe命令对某个字节码文件进行解释运行,
         *              相当于将某个字节码文件加载到内存中,称为类的加载,加载到内存中的类,称其为运行时类
         *              此运行时类就作为Class的一个实例
         *         2.Class的实例对应着一个运行时类
         *         3.加载到内存中的运行时类,会缓存一定的时间之内,我们可以通过不同的方式获取此运行时类
         *         
         * */
        /*
         * 获取Class实例的四种方式
         * */
        @Test
        public void test3() throws ClassNotFoundException {
            //方式1:调用运行时类的属性;Class后面不加泛型也可以
            Class<Person> clazz1 = Person.class;
            System.out.println(clazz1);
            
            //方法2:通过运行时类的对象
            Person p1 = new Person();
            Class clazz2 = p1.getClass();
            System.out.println(clazz2);
            
            //方式3:调用Class静态方法forName(String classpath),classpath为类所在路径
            Class clazz3 = Class.forName("reflection.Person");
            System.out.println(clazz3);
        
            //方式4.使用类的加载器
            ClassLoader classLoader = ReflectionTest.class.getClassLoader();
            classLoader.loadClass("reflection.Person");
            Class clazz4 = classLoader.loadClass("reflection.Person");
            
            System.out.println(clazz1==clazz2);
            System.out.println(clazz1==clazz3);
            System.out.println(clazz1==clazz4);
        }
        
        
        
    
    } 
    View Code

    类加载器的理解

    package reflection;
    
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.util.Properties;
    
    import org.junit.jupiter.api.Test;
    /*
     * 类的加载过程:
     *     1.类的加载:将类的class文件读入内存,并为之创建Class对象,此过程由类加载器完成
     *     2.类的链接:将类的二进制数据合并到JRE中,设置static变量的默认值(0,null,""等)
     *     3.类的初始化:JVM负责初始化,按顺序执行执行静态代码块和类属性的赋值
     * 
     * */
    
    
    /*
     * 了解类的加载器
     * 
     * */
    
    public class ClassLoaderTest {
        @Test
        public void test1() {
            //对于自定义类,得到ClassLoaderTest的类加载器:属于System Classloader,即系统类加载器
            ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
            System.out.println(classLoader);
            
            //调用系统类加载器的getParent().得到Extension Classloader,即扩展类加载器
            ClassLoader classLoader2 = classLoader.getParent();
            System.out.println(classLoader2);
            
            //Bootstap Classloader负责加载java核心类库,得不到了
            ClassLoader classLoader3 = classLoader2.getParent();
            System.out.println(classLoader3);
            
            //和3同理,String是java核心类库的
            ClassLoader classLoader4 = String.class.getClassLoader();
            System.out.println(classLoader4);
        }
        
        //读取读取配置文件
        @Test
        public void test4() throws Exception {
            //方式1
            Properties pros = new Properties();
            FileInputStream fis = new FileInputStream("jdbc.properties");
            pros.load(fis);
            
            String user = pros.getProperty("user");
            String passwd = pros.getProperty("password");
            System.out.println(user+passwd);
            
        }
            
    }
    View Code

    通过反射创建运行时类的对象

    package reflection;
    
    import org.junit.jupiter.api.Test;
    
    /*
     * 通过反射创建对应的运行时类的对象
     * */
    
    public class NewInstanceTest {
        
        @Test
        public void test1() throws InstantiationException, IllegalAccessException {//实例化异常, 权限异常
            Class<Person> clazz = Person.class;
            Object object = clazz.newInstance();
            System.out.println(object);
            
            /*
             * newInstance()创建对应的运行时 类的对象
             * 内部调用了空参数构造器
             * */
            
            Person person = clazz.newInstance();//这儿直接能得到person类运行时类对象
            System.out.println(person);
        }
        
        @Test
        public void test2() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
            String classPath = "";
            classPath = "java.util.Date";
            System.out.println(getInstance(classPath));
            classPath = "reflection.Person";
            System.out.println(getInstance(classPath));
        }
        //此方法创建一个指定全类名的实例
        public Object getInstance(String classPath) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
            Class clazz = Class.forName(classPath);
            return clazz.newInstance();
        }
    }
    View Code
  • 相关阅读:
    2020 ICPC 沈阳站 M. United in Stormwind
    [笔记] 中世纪反演魔法
    [模板] 多项式工业
    HDU 1187 Big Event in HDU
    洛谷 P2000 拯救世界
    HDU 1085 Holding Bin-Laden Captive!
    HDU 1028 Ignatius and the Princess III
    性能测试——jmeter接口测试复习——请求元件之配置元件——参数化——txt与csv
    性能测试——jmeter接口测试复习——请求元件之用户自定义变量——即参数化
    性能测试——jmeter接口测试复习——断言之响应断言——放在某个http请求下面,用来判断返回code、header、message中是否包含预期的值
  • 原文地址:https://www.cnblogs.com/zsben991126/p/11888613.html
Copyright © 2020-2023  润新知