获取Class实例的方式与类加载器

1. java.lang.Class:   是反射的源头

2.如何获取Class的实例(3种)

3.关于类的加载器

TestReflection2

package com.aff.reflection;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.junit.Test;
/*
  java.lang.Class:   是反射的源头
                            我们创建一个类,通过编译(javac.exe),生辰对应的.class文件。
                            之后我们使用java.exe加载(JVM的类的加载器)此class文件,
                            .class文件加载到内存后,就是一个运行时类,存在缓存区中。
                            那么运行时类本身就是一个Class的实例
 1.每一个运行时类只加载一次
 2.有了Class实例以后,才能进行如下的操作
                          ①创建运行时类的对象
                          ②可以获取对应的运行时类的完整结构(属性,方法,构造器,内部类。。。)
                          ③调用对应的运行时类的指定的结构(属性,方法,构造器)
                          ④反射的动态代理
 */

public class TestReflection2 {
    // 关于类的加载器
    @Test
    public void test5() throws IOException, ClassNotFoundException {
        ClassLoader loader1 = ClassLoader.getSystemClassLoader();
        System.out.println(loader1);// sun.misc.Launcher$AppClassLoader@7852e922

        ClassLoader loader2 = loader1.getParent();
        System.out.println(loader2);// sun.misc.Launcher$ExtClassLoader@330bedb4

        ClassLoader loader3 = loader2.getParent();
        System.out.println(loader3);// null

        // 自定义的类是由系统加载器加载的
        Class clazz = Person.class;
        ClassLoader loader4 = clazz.getClassLoader();
        System.out.println(loader4);// sun.misc.Launcher$AppClassLoader@7852e922

        // String,Object又由上面的引导类加载的,所有加载不到的
        String className = "java.lang.String";
        Class clazz2 = Class.forName(className);
        ClassLoader loader5 = clazz2.getClassLoader();
        System.out.println(loader5);// null

        // 掌握如下:
        //法一:指定目录下的jdbc.properties,可具体的包里
        ClassLoader loader = this.getClass().getClassLoader();
        InputStream is = loader.getResourceAsStream("com\\aff\\reflection\\jdbc.properties");
        //法二:当前工程下jdbc.properties
        //FileInputStream is  = new FileInputStream(new  File("jdbc.properties"));
        
        Properties pros = new Properties();
        pros.load(is);
        String name = pros.getProperty("user");
        String password = pros.getProperty("password");
        System.out.println(name + "\n" + password);//root  \n  123abc

    }

    // 如何获取Class的实例(3种)
    @Test
    public void test4() throws ClassNotFoundException {
        // 1.调用运行时类本身的 .class
        Class clazz1 = Person.class;
        System.out.println(clazz1);// class com.aff.reflection.Person
        System.out.println(clazz1.getName());// class com.aff.reflection.Person
        Class clazz2 = String.class;
        System.out.println(clazz2.getName());// java.lang.String

        // 2.通过运行时类的对象获取
        Person p = new Person();
        Class clazz3 = p.getClass();
        System.out.println(clazz3.getName());// com.aff.reflection.Person

        // 3.通过Class的静态方法获取,t通过此方式,体会,反射的动态性
        String className = "com.aff.reflection.Person";
        Class clazz4 = Class.forName(className);
        // clazz4.newInstance();//可以操作很多事
        System.out.println(clazz4.getName());// com.aff.reflection.Person

        // 4.通过类的加载器(了解)
        ClassLoader classloader = this.getClass().getClassLoader();// 得到类加载器
        Class clazz5 = classloader.loadClass(className);//
        System.out.println(clazz5);// class com.aff.reflection.Person
    }

    @Test
    public void test3() {
        Person p = new Person();
        Class clazz = p.getClass();
        System.out.println(clazz);// class com.aff.reflection.Person
    }
}

 

3.关于类的加载器

类加载器是用来把类(class)装载进内存的。

JVM 规范定义了两种类型的类加载器:启动类加载器(bootstrap)和用户自定义加载器(user-defined class loader)。

JVM在运行时会产生3个类加载器组成的初始化加载器层次结构 ,如下图所示:

 

posted @ 2020-04-02 21:12  林淼零  阅读(697)  评论(0编辑  收藏  举报