Java 类加载器

类加载器

方法区:类:Demo.class    静态区:静态方法/main方法

类加载器 (静态之前)自动在堆中创建 Demo字节码文件对象  

类的初始化

加载 class文件读入内存,并为之创建一个Class对象

连接

验证 内部结构,与其他类的协调

准备 静态成员分配内存,设置初始值

解析 符号引用替换为直接引用

初始化 就是我们以前讲过的初始化步骤

类初始化时机

1. 创建类的实例 new cls()

2. 类的静态变量,或者为静态变量赋值  cls.a

3. 类的静态方法  cls.method()

4. 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象

5. 初始化某个类的子类  new sun()   

6. 直接使用java.exe命令来运行某个主类  运行 main

类加载器的组成

Bootstrap ClassLoader 根类加载器   Java核心类的加载

  如System,String等。在JDKJRElib目录下rt.jar文件中

Extension ClassLoader 扩展类加载器 负责JRE的扩展目录中jar包的加载。

  在JDKJRElib目录下ext目录

System ClassLoader 系统类加载器  加载包

  负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径。

反射(通过字节码文件对象,获取其所有属性方法)

反射需要用到的成员及方法:

Class

Constructor 构造

Method 方法

Filed 字段

instance 实例

invoke 执行

reflect

//Class类:描述文件对象

//Constructor类:描述构造方法的类

//Method类:描述方法的类

//Field类:描述变量的类

 

public static void main(String[] args) throws Exception{

//获取文件字节码对象(只有一个)     类进入内存

//Person p=new Person(); Class c=p.getClass();//1.通过对象获取

//Class c1=Person.class;//通过类名获取

Class c2=Class.forName("com.shangwu.Person");//Class.静态(包名.类名)

System.out.println(c);//class com.shangwu.Person

//获取构造方法数组    Constructor<T>

//Constructor[] cons=c.getConstructors(); //所有公共构造方法数组

Constructor[] cons = c.getDeclaredConstructors();//所有构造方法数组

for(Constructor con:cons){ System.out.println(con); }//遍历

//获取构造方法     Constructor<T>

//Constructor con=c.getConstructor();//公共构造方法对象    空参

//Constructor con=c.getConstructor(String.class,int.class); // 有参

Constructor con=c.getDeclaredConstructor(String.class);//私有有参构造

con.setAccessible(true);//暴力反射时 取消java语言的访问检查

 

//通过获取的构造方法 创建对象

//Object obj=con.newInstance();//空参构造  Person对象    多态

//Object obj=con.newInstance("张三",18);//有参构造 Person对象

Object obj=con.newInstance("李四");//私有有参构造 Person对象

//Object obj2=c.newInstance();//类文件对象 调用公共空参构造 对象

Person p2=(Person)obj; //向下转型

p2.eat();

//获取成员变量数组

//Field[] fields = c.getFields(); //获取所有公共成员变量数组

Field[] fields=c.getDeclaredFields();//获取所有成员变量数组

for(Field f:fields){ System.out.println(f); }

//获取成员变量

Field nameField=c.getField("name");//获取类中的公共成员变量name

//Field ageField = c.getDeclaredField("age"); //私有/公共成员变量age

//ageField.setAccessible(true); //取消 Java 语言访问检查

//对象变量赋值 取值

nameField.set(obj,"张三");  //指定对象 对应变量 赋值

String name=(String) nameField.get(obj);//返回指定对象 对应变量的值

 

//获取成员方法数组

Method[] methods = c.getMethods();//获取所有公共成员方法

//Method[] methods=c.getDeclaredMethods();//获取所有成员方法

for(Method m:methods){ System.out.println(m); }

//获取的公共有参方法并调用

Method mSetAge=c.getDeclaredMethod("setAge",int.class);//方法名参数

//mSetAge.setAccessible(true); //取消 Java 语言访问检查

Method mGetAge=c.getMethod("getAge");//获取公共 方法名 无参数

Object result =mSetAge.invoke(obj, 18); //指定对象 调用对应方法

int age=(int)mGetAge.invoke(obj); //对象 调用方法 返回值 转型

Method mMain=c.getMethod("main", String[].class);  //获取main函数

mMain.invoke(null,(Object)args); //调用main函数 传参 数组转对象

}               //防止传参时 数组自动拆分

反射配置:

public class Student {
    public void study(){
        System.out.println("学生学习");
    }
}
config.properties文件(File)内容:
#ClassName=com.xiawu.Worker
#MethodName=work
ClassName=com.xiawu.Student
MethodName=study

public class FanshePeizhi {
    //Person  Student  Worker
    
    public static void main(String[] args) throws Exception {
        //1.准备 配置文件   键值对 config.properties
        //2.读取键值对
        FileReader fr=new FileReader("config.properties");
        Properties pro=new Properties();
        pro.load(fr);
        fr.close();
        
        //从集合中获取类名 和 方法名
        String className=pro.getProperty("ClassName");
        String methodName=pro.getProperty("MethodName");
        //System.out.println(methodName);
        
        //反射获取指定类的class文件对象
        Class c=Class.forName(className);    //类文件对象

        Object obj=c.newInstance();            //创建对象

        Method method=c.getMethod(methodName);    //获取指定方法
        method.invoke(obj);                        //运行制定方法
    }
}

泛型擦除:

//泛型擦除(通过反射向有泛型约束的集合中,添加任意类型的元素)
public class FanxingCachu {
    public static void main(String[] args) throws Exception {
        ArrayList<Integer> arr=new ArrayList<Integer>();
        arr.add(1);
        //arr.add("你好");

        Class c=arr.getClass();//ArrayList类文件对象

        Method method=c.getMethod("add", Object.class);//获得add方法
        method.invoke(arr, "你好");    //调用方法(对象,方法参数)
        System.out.println(arr);
    }
}
原文地址:https://www.cnblogs.com/javscr/p/10252826.html